API App Messaging (Part 1)

The microservices architecture is perfect method to organize the API App. However, the messaging between the modules must be pain free. We have provided the Queueing infrastructure to enable both asynchronized or synchronized communication.

The Sample API App

The following sample demonstrate asynchronized messaging with a sample API App. The API returns search results from Github and Bitbucket code repositories. It is also a demonstration of API to API integration with public APIs.

Microservices Async Messaging

Separation of Concerns

Isolating each search function in a microservice container brings many administrative benefits. Yet another advantage is the ability to scale the services in order to accommodate the different workloads.

Scaling

Microservices Scaling
Horizontal Scaling

In the above configuration the Bitbucket component includes x 2 instances. This will enable the API to service two Bitbucket searches in parallel. Furthermore, deploying the API App in a computing instance with at least two CPUs ensure the underlying system itself is able to handle simultaneous queries.

Vertical Scaling

Each component is again vertically scaled to 128MB giving a total of 256MB. The amount of memory can be adjusted depending on the workload

Load Balancing

Microservices Scaling

The query requests arrives in a pipeline where each component instance services a request in a round-robin fashion. This ensures the work is nicely load-balanced.

The API

GET v1/Search/{text}

The REST endpoint is a GET request with the parameter {text} providing the keyword. 

The Request Endpoint

The client API request is handled in a controller class.

Step 1. Dispatch search jobs : A “Scatter-Gather” approach is used to conduct the search when a request arrives. The probe is sent to each service component via the queue. The correlation Id of each probe is recorded so that the returned data can be matched to the initial call.

Step 2. Do other work : Do other work while the queries are performed.

Step 3. Collect the search results : The results of the search are available on the return queue. Pick up the results and return it to the client.

The Request Function

The request function simply sends a request and returns the correlationId of the request.

The Collect Results Function

The returned results are collected here. The results are matched to a correlation id collected previously. This way we ensure the correct results are returned.

The Search Modules

Here I use the Bitbucket module to demonstrate the job handler. The process-flow of the Github module is identical. The output from this module is received by the CollectResults function above.

Step 1. Read the next received request : The job handler waits for a search request to arrive. When a request arrives the message body containing the data and headers containing meta data are extracted.

Step 2. Check if a search request was received : We can determine if its a search request by inspecting the message type.

Step 3. Perform a search and return the result : Here we query the Bitbucket repositories for files containing the keyword and return the result in JSON format.

Step 4. Create a response to send back : A standard response is created with the result data. A standard response contain error codes and messages that the client can determine if the request was successful.

Step 5. Send back the result to the handler : The received message meta data contain the replyTo queue to send back the response. Send the response to this queue where it is processed by the CollectResults function.

The Results

The following image show a sample query result on the Swagger UI. The Handled-By field returns the component id that handled the query.

On the production system you will see the Handled-By value changing between bitbucket.0 and bitbucket.1 components indicating the messages are serviced in a round-robin fashion.

Messaging Result

Conclusion

I hope I have explained how async messaging works on the platform. We have made things easy providing all you need to develop your API Gateway. In the next article I shall discuss how to use sync messaging using RPC style messaging.

I should also explain the library we use for messaging Nester.Works is completely customizable and the source code is available on Github.

I welcome any comments or other feedback.

Further Information