Seminar 2: Building Client/Server Connections
Goal: Dive into the fundamentals by establishing client-server connections, a cornerstone for distributed systems interactions.
Introduction
In this second session of our Distributed Systems practice, you are entrusted with the architecting of the checkout process for an online bookshop. The task at hand demands the design and implementation of client/server connections to seamlessly link the frontend and a network of backend microservices. Provided with a ready-made Frontend App, an OpenAPI specification of a RESTful API, an organized backend repository, and sample code snippets, your primary objective is to construct the backbone of the bookshop checkout process. Employing REST for frontend-backend communication and gRPC for orchestrated backend microservices interactions, your responsibilities include extending the given sample code to handle the REST request, establishing seamless communication channels through gRPC, and conceptualizing the execution of the backend services.
Scenario
In the given scenario, the flow initiates when a user finalizes an order in the Frontend, triggering a POST request upon clicking the order confirmation button. This request, containing the order data, is transmitted to the backend, specifically to the orchestrator service. Functioning as a central coordinating entity, the orchestrator assumes responsibility for directing subsequent steps in the execution flow. This initial phase encapsulates the process triggered by the user.
In the subsequent phase of this process, the orchestrator service takes charge, as the master thread. It deploys worker threads, adhering to a multithreading model, to efficiently handle parallel operations. These worker threads are tasked with dispatching the order data via gRPC to three distinct services — namely, a fraud detection service, a transaction verification service, and a suggestions service. Each of these services independently conducts its designated operations and promptly returns the results to the orchestrator threads. The orchestrator then combines these results into a conclusive decision — whether the order is approved or rejected. This outcome is subsequently communicated back to the user frontend, thereby completing the orchestrated cycle of actions initiated by the user's initial order confirmation.
Task
- REST Implementation: Edit and implement the code to handle REST API requests originating from the Frontend. This ensures a seamless communication channel between the user interface and the backend services. The initial code can be found under the orchestrator folder, and the API specification under the utils/api folder (check the bookstore.yaml file for the bookstore example).
- Orchestrator Service: Following the API implementation, upon a user request, develop the logic to deploy worker threads for parallel processing. These threads will be responsible for dispatching the order data to the designated backend microservices and wait for the respective results.
- Backend Microservices: Develop three new backend microservices—fraud detection, transaction verification, and suggestions. Follow the same structure as provided in the sample code. Each service should have its own folder, with its application code and one Dockerfile that containerizes the code. The docker-compose file, at the top level in the repository, should list and orchestrate the new services with the necessary configurations (name, port, volumes, etc…).
- The fraud detection service should listen on port 50051. For now, you are allowed to implement some dummy logic to determine if an order is fraudulent or not. Real world applications usually deploy complex AI architectures that use large quantities of user data to quickly and reliably detect fraud in user activities. You are free to explore simpler AI mechanisms for this use case. Bonus points will be awarded for this extra work, during Checkpoint #1 evaluation.
- The transaction verification service should listen on port 50052. Like the fraud detection service, at this stage, you are also allowed to implement some simple logic that determines if a transaction is valid or not. For instance, you can check if the list of items is not empty, the required user data is all filled-in, and the credit card format is correct, among other checks. Feel free to structure the logic as you see fit.
- The suggestions service should listen on port 50053. Similarly, the suggestions service should be as simple as calculating and sending back a list of new book suggestions. You can have a static books list and simple computations to determine a subset of the list to send back as response. Or, for more bonus points, you can try to employ an AI mechanism to suggest new books.
- gRPC Communication Setup: Establish communication channels to the three services - fraud detection, transaction verification, and suggestions - using gRPC, to which the orchestrator worker threads should send a request, and from which they should expect a response. Check the utils/pb folder for the gRPC proto file specification and follow the sample code provided in the orchestrator and fraud_detection folders as an example to establish gRPC client/server connections.
- Results Consolidation: In the orchestrator service, devise a mechanism to combine the results received from the three backend microservices. It should wait for the threads to finish and combine their results: if fraud was detected, or the transaction verification failed, send “Order Rejected” to the user, otherwise send “Order Approved” along with the list of book suggestions. Finalize the logic to communicate the decision—whether the order is approved or rejected—back to the user frontend. Check the API specification for the concrete information on the type of response objects required. This completes the orchestrated cycle initiated by the user's initial order confirmation.
- System logging: Add relevant logs in all your services, targeting the most relevant actions, like the receiving of a request, the spawning of a new thread, the returning of a response, among others.