When designing a set of micro services to work in a client system it is advised to, instead of jumping in and thinking about the services themselves, think about the solution in the following way:
- Messages
- Activities
- Services
Messages
Messages are a fundamental concept to micro service based architecture. Messages are a plain English description of the tasks that the system as a whole will expect to undertake. All architecture of systems should start here.
**Note: there is a template spreadsheet in the company Google Sheets named 'Microservice Design' that can be useful to fill in whilst walking through this process.**
For the remainder of this article, I am going to use a simple solution that receives JSON data from an external system, stores the JSON and any requisite byte[] attachments in storage and sends a request to a OCR engine to index the document.
NameDescriptionSynchronous (S) or Asynchronous (A) inboundrequest:postReceive a new request for processingSdatastore:saveSave the inbound request to a datastoreSdatastore:listList all documents in the datastore with filtering (awaiting indexing, awaiting export)Sdocumentstore:saveSave inbound request attachmentsSdocumentstore:retrieveRetrieve inbound request documentsSocr:createCreate a new OCR taskSinfo:newinbounddocumentRaise an event notifying that a new document has been savedAinfo:documentsentforocrRaise an event notifying that a document has been sent for OCRAinfo:documentfailedforocrRaise an event notifying that a document has failed to be sent for OCRA
In the above table, all the messages the system will be processing are listed along with a useful description of what that specific message is intended to achieve. Determining if a request should be Synchronous (S) or Asynchronous (A) can be done by using a very simple rule of thumb, does the sender need to know if the result of the request.
In the instance above of saving data to a datastore, the service request the storage of data needs to receive some kind of confirmation that the data has indeed been successfully persisted.
Activities
Activities are the processes the system will action, using the messages detailed in the previous step. NameMessage FlowNew Inbound Request1. inboundrequest:post 2. datastore:save 3. documentstore:save 4. info:newinbounddocumentSend for OCR1. datastore:list 2. documentstore:retrieve 3. ocr:create 4. info:documentsentforocr OR info:documentfailedforocr
Running through this step should then give you enough information to make logical groupings to decide on the services themselves
Services
Services are the actual application components that make up the system architecture. NameDescriptionSendsReceivesfrontHandles external HTTP requests and sits behind a load balancerinboundrequest:post datastore:list inboundTranslates the inbound request into formatted data and saves any physical file attachmentsdatastore:save documentstore:save info:newinbounddocumentinboundrequest.postrequest-storeHandles persistence of request and index data datastore:save datastore:listocrHandles moving of documents from storage to the OCR enginedatastore:list documentstore:retrieve ocr:create info:documentsentforocr info:documentfailedforocrinfo:newinbounddocument
There are numerous ways these set of services could be set out. There is an argument to combine the request-store and inbound processor into a single service to make processing of requests faster but keeping a split allows for easy update of the data persistence layer without needing to worry about how inbound requests are handled.
When building micro services it is good practice to only have one single service that is exposed to external requests, an API gateway. That is the purpose of 'front'. All other services will be contained within a sealed network with no inbound network connectivity. There are numerous frameworks available, Ocelot ([https://github.com/ThreeMammals/Ocelot](https://github.com/ThreeMammals/Ocelot) ) being one of the most commonly used.