Title Page Copyright and Credits Hands-On Microservices with Rust About Packt Why subscribe? Packt.com Contributors About the author About the reviewer Packt is searching for authors like you Preface Who this book is for What this book covers To get the most out of this book Download the example code files Download the color images Conventions used Get in touch Reviews Introduction to Microservices Technical requirements What are microservices? Why we need microservices How to deploy a microservice Docker Continuous Integration How to split a traditional server into multiple microservices Reasons to avoid monoliths Impossible to scale vertically Impossible to update and deploy only one feature The failure of one server affects all features Breaking a monolithic service into pieces Definition of a REST API User registration microservice E-mail notifications microservice Product catalog  microservice Shopping cart microservice Payment Integration microservice Statistics collecting microservice Transformation to microservices Reusing existing microservices Why Rust is a great tool for creating microservices Explicit versus implicit Minimal amount of runtime errors Great performance Minimal dependencies burden Summary Further reading Developing a Microservice with the Hyper Crate Technical requirements Binding a Tiny Server Adding necessary dependencies The main function of the server Address of the server Server instances Setting the requests handler Adding the server instance to a runtime Building and running Rebuilding on changes Handling incoming requests Adding a service function Implementing a service function Index pages Implementing the REST principles Adding a shared state Accessing a shared state from a service function Parsing paths in a microservice Implementing REST methods Extracting the user's identifier Getting access to the shared data REST methods POST – Creating data GET – Reading data PUT – Updating data DELETE – Deleting data Routing advanced requests Defining paths with regular expressions Adding the necessary dependencies Writing regular expressions Path for index page Path for user management  Path for the users list Matching expressions Summary Logging and Configuring Microservice Technical requirements Adding logging to a microservice Random-value-generating microservices The log crate Loggers Log levels Logging messages Custom level of messages Checking logging is enabled Own target Using logging Configuring a logger with variables RUST_LOG RUST_LOG_STYLE Changing the RUST_LOG variable to your own Reading environment variables Standard library Using the .env file Using the dotenv crate Adding variables to the .env file Parsing command-line arguments Using the clap crate Adding dependencies Building a parser Reading arguments Usage How to add subcommands Reading the configuration from file Adding the TOML config Adding dependencies Declaring a struct for configuration Reading the configuration file Joining all values by a priority Creating and using the configuration file Summary Data Serialization and Deserialization with the Serde Crate Technical requirements Data formats for interaction with microservices The serde crate Serializing responses Deserializing requests Tweaking serialization Changing the case of names Removing a nesting Using specific names for a tag and content Any Value Using hyper Reading a body from a stream Custom types Custom serialization Custom deserialization Custom error types with the failure crate Binary data Compiling, running, and testing Microservices with multiple formats Different formats Parsing a query Checking different formats Transcoding XML support Summary Understanding Asynchronous Operations with Futures Crate Technical requirements Basic asynchronous types Basic types of future crate Using the Future trait Using the Stream trait Using Sink to send data back The channel module Channels for sending multiple messages Single-Producer Single-Consumer  Multi-Producer Single-Consumer Multi-Producer Multi-Consumer  Example of usage One-shot Using channels to use Sink in multiple places Executors Running futures and streams with blocking Using an executor The async/await syntax Creating an image service Uploading images The tokio crate Asynchronous input/output of files Multipart form requests Downloading images sendfile for sending files Testing the service Summary Reactive Microservices - Increasing Capacity and Performance Technical requirements What is a reactive microservice? Loose coupling Message-driven applications Asynchronous Should a reactive microservice be asynchronous? Reactive microservices with futures and streams Message brokers Remote procedure calls JSON-RPC gRPC Thrift Other RPC frameworks RPC and REST Reactive manifesto Understanding JSON-RPC How JSON-RPC works Creating a microservice Dependencies Client Worker Server Compiling and running Learning about gRPC How gRPC works Creating a microservice Dependencies Protocol Generating interfaces Shared client Client Server implementation Service implementation Handlers The main function Worker Compiling and running Summary Reliable Integration with Databases Technical requirements PostgreSQL Setting up a test database Simple interaction with a database Adding dependencies Creating a connection Wrapping with a tool Compiling and running Connection pools Creating a pool Parallel imports with the rayon crate Rayon MySQL Database for tests Connecting with the r2d2 adapter Adding dependencies Database interaction functions Creating a connection pool Redis Bootstrap database for tests Creating a connection pool Dependencies Adding commands and interaction functions Data manipulation functions Parsing arguments Connecting to Redis Executing subcommands Testing our Redis example MongoDB Bootstrapping a database for testing Connecting to a database using the r2d2 pool Interaction functions Parsing arguments Creating a connections pool Implementing subcommands Testing DynamoDB Bootstrapping a database for testing Connecting to DynamoDB Adding dependencies Interaction functions Parsing command-line arguments Testing Summary Interaction to Database with Object-Relational Mapping Technical requirements The diesel crate Adding the necessary dependencies diesel_cli Creating migrations Declaring the data structure Models Connecting to a database Parsing arguments Creating a connection Implementing subcommands using a DSL Adding a user subcommand implementation Listing users subcommand implementation Testing Complex database structure Business logic of the example application API methods Database structure and migrations Diesel initial setup up.sql down.sql Users table up.sql down.sql Channels table up.sql down.sql Memberships table up.sql down.sql Messages table up.sql down.sql Schema Models User Channel Membership Message Database interaction API crate Api Register user Create channel Publish channel Add member Add message Delete message Testing the crate Summary Simple REST Definition and Request Routing with Frameworks Technical requirements Rouille Creating a microservice Bootstrapping a server Handling requests Root handler Sign-up handler Sign-in handler Default handler Compiling and running Nickel Creating a microservice Bootstrapping a server Handling requests Worker for sending emails Compiling and running Rocket Creating a microservice Bootstrapping a server Handling requests Database schema and models Compiling and running Gotham Creating a microservice Types of framework The main function Handler implementation Running and testing Summary Background Tasks and Thread Pools in Microservices Technical requirements Interacting with threads Synchronous or asynchronous? IO-bound versus CPU-bound tasks Synchronous tasks inside asynchronous contexts The limitations of using IO operations on files Spawning a thread for image processing Interacting with a thread in an asynchronous way Using thread pools CpuPool The blocking section Actors Basics of the actix framework Implementing actors The count actor Types Actor Message Handler The log actor Types Actor Message Handler The resize actor Types Actor Message Handler Using the server with actors Requests handler Building and running Summary Involving Concurrency with Actors and the Actix Crate Technical requirements Actor concurrency in microservices  Understanding actors Actors in microservices The Actix framework Creating a microservice with actix-web Bootstrapping an actix-web server Starting a server App creation Scope and routes Static files handler HTTP client GET requests POST requests Handlers Signup Signin New comment Comments Counter Middleware Building and running Using databases The database interaction actor Actors Messages Setting a value message Get value message Link to actor Using database actors WebSocket Repeater actor Actors Messages Updating the message Control message The notification actor Actor Handlers Adding WebSocket support to a server Summary Scalable Microservices Architecture Technical requirements Scalable architecture Basic ideas Message brokers and queues RabbitMQ Kafka Application bottlenecks Scalable application with Rust and RabbitMQ Bootstrap message broker for testing Dependencies Abstract queue interaction actor Dependencies Abstract messages handler Actor Handling an incoming stream Sending a new message Utility methods Crate Request and response Worker Dependencies Handler main function Server Dependencies Shared state Server handler Requests handlers Index handler Tasks handler Upload handler main function Testing How to scale this application Summary Testing and Debugging Rust Microservices Technical requirements Testing microservices Unit testing Mocking Starting a server for testing Making requests Implementing tests Running our tests Integration testing Starting an application instance Dependencies Utils The integration testing client Types Users Content Mailer Router Debugging microservices curl Postman mitmproxy LLDB Visual Studio Code Structural logging Example Building and testing Distributed tracing Starting Jaeger Generating spans Compile and run Summary Optimization of Microservices Technical requirements Performance-measuring tools Welle Drill Measuring and optimizing performance Basic example Performance Optimizations State sharing without blocking Reusing values by references Caching Compilation with optimizations Optimization techniques  Link-time optimizations Abort instead of panicking Reducing the size of binaries Isolated benchmarks Profiling Summary Packing Servers to Containers Technical requirements Building a Docker image with a microservice Creating an image with the Rust compiler Users microservice image .dockerignore Dockerfile Building an image Starting a container Content microservice image Email microservice image Router microservice image DBSync worker image Dependencies The main function Hiding microservice source code  Composing a microservice set Application definition Database container A container with an email server DBSync worker container Mails microservice container Users microservice container Content microservice container Router microservice container Running the application Adding persistent state to the application Running the application in the background Summary DevOps of Rust Microservices - Continuous Integration and Delivery Technical requirements Continuous integration and continuous delivery Continuous integration  Continuous delivery  Container orchestration Rust tools Rustfmt Installation Usage Configuration Clippy Installation Usage Configuration Recommended code attributes Rustfix Installation Usage Cargo test CI and CD tools TravisCI AppVeyor Jenkins Demonstration of continuous integration Docker Compose The SCM server The CI server The CI agent The image Configuring Gogs Configuring TeamCity Authorizing agents Creating a project Building steps for Rust Building with CI Summary Bounded Microservices with AWS Lambda Technical requirements Serverless architecture AWS Lambda Azure Functions Cloudflare Workers IBM Cloud Functions Google Cloud Functions Minimal Rust microservices for AWS Lambda Dependencies Developing a microservice Building Deployment Serverless Framework Preparation Implementation Dependencies Handler Request and response types Functions Configuration Resources Deployment Permissions Script Running Testing Updating and removing Summary Other Books You May Enjoy Leave a review - let other readers know what you think