Microservice Interaction Patterns

To enable federation of INTERSECT microservices, it is useful to understand the types of interactions a given microservice may reasonably expect from one of its clients. As shown in Fig. 117, we have identified three common patterns that substantively cover the expected interactions: Command, Request-Reply, and Asynchronous Status or Event.

The Command Interaction Pattern involves the client asking the microservice to do something. The microservice typically responds immediately with a simple acknowledgement that the command has been received successfully or some error status indicating why the command was not acceptable. A command may initiate an activity within the microservice, but that activity is not ordered with respect to the command acknowledgment message. Thus, commands are asynchronous interactions from the client perspective.

The Request-Reply Interaction Pattern has the client making a request of the microservice that includes an expected reply containing pertinent information or data related to the request. Because the reply is not sent until the request has been fully processed, this is a synchronous interaction pattern from the client perspective.

The Asynchronous Status or Event Interaction Pattern represents cases where the microservice generates status or event information that is broadcast to any interested parties at irregular intervals as a result of internal operational state changes or ongoing activities. Events are informational in nature and there is no expectation that the associated message must be delivered. However, status messages are typically associated with activities initiated by clients, and therefore must provide some limited form of message durability to ensure that the message is delivered to at least one interested party. Each of these interaction patterns supports implementations based on RESTful client-server communication or asynchronous messaging, as described later in Implementing Microservice Interaction Patterns.

Interaction patterns for INTERSECT microservices

Fig. 117 Interaction Patterns for INTERSECT Microservices

The messages used in these interaction patterns also share common information that should be included in the message contents. For instance, in all three patterns, messages should include information that describes the source of the message and the specific type of Command, Request, Reply, Event, or Status. For a Command message, the type should indicate the requested action. For a Request or Reply message, the type should indicate the requested information or data. For an Event message, the type should identify the generator of the event. For a Status message, the type should identify the activity or resource whose status is being reported. This type information can also be used by the receiver to know what other information may be included in the message, such as any parameters or data associated with a Command, Request or Reply, or codes and descriptions associated with a particular Event. Similarly, a timestamp associated with the sending of the initial message is useful in all three patterns. For a Command or Request message, this timestamp represents the time when a client issued the request, which may be used in situations requiring a completion deadline or for communication retry purposes. For an Event or Status message, the timestamp indicates when the event or status change occurred. Finally, it is useful within Command and Request-Reply interactions to support trace identifiers that clients can use to associate messages with specific client state. Trace identifiers are particularly useful when a client interaction requires the target microservice to make further requests of other microservices. The target microservice should pass on the trace identifier it received from the client along with its own external requests. When combined with a distributed message logging facility, the trace identifier enables a complete view of the request progress from the initial client, through one or more remote microservice requests and replies, and ending with a reply to the initial client. This complete traceability of requests through microservices is also crucial for operational insight when investigating and resolving problems encountered in deployed microservices architectures.

Sequence Diagrams for Microservice Interactions

Throughout the INTERSECT Open Architecture documentation, we utilize sequence diagrams to depict interactions between microservices. A sequence diagram uses parallel entity lifelines to show the actions taken by entities and interactions between entities. Fig. 118 shows an example sequence diagram for microservice interactions. As shown in the figure, boxes are used to denote INTERSECT systems and services, and individual entity lifelines are shown for each microservice capability within a service. Example messages between services and asynchronous events are shown for each of the three common microservice interaction patterns.

Each microservice interaction sequence diagram may include optional components such as preconditions that should be satisfied, assumptions that hold for certain interactions, important service interactions with processes or activities external to the INTERSECT ecosystem, and notes that provide information about relevant service actions or behavior. A sequence diagram may also incorporate sub-sequences shown in another diagram through a reference to the title of the other diagram.

INTERSECT Microservice Interaction Sequence Diagram Example

Fig. 118 Example INTERSECT microservice interaction sequence diagram showing common components.

Implementing Microservice Interaction Patterns

As previously introduced in Microservices Architecture, there are two common communication architectures used for microservices: client-server and asynchronous messaging. Here we describe the relative merits of each communication architecture, followed by example approaches for implementing the common interaction patterns introduced in Microservice Interaction Patterns using each architecture.

The predominant approach to client-server communication architecture involves RESTful microservices that provide a synchronous request-response model based on representational state transfer over HTTP. Such a 1:1 pattern is suitable for many forms of requests, including control commands and simple information queries. However, the use of synchronous request-response is not advisable for 1:N interactions where one request is sent to many services, due to the serialization of the requests at the client and the resulting impact to completion latency. Furthermore, the use of RESTful services for use cases involving many microservices often leads to tight coupling that reduces reuse and service independence.

Asynchronous messaging supports both 1:1 and 1:N communication patterns using a message broker that delivers messages associated with a specific topic to any interested parties. When the messages represent events, this communication architecture is often referred to as an event-based architecture. Additional benefits of asynchronous messaging include the ability to independently scale clients and servers, support for concurrent providers of the same service, support for transient services, and simplified communication context management due to the use of a central message broker.

Fig. 119 shows a typical implementation strategy for the Command Interaction Pattern using both client-server communication and asynchronous messaging. With client-server communication, sending the Command message involves use of an HTTP POST operation, and the message receipt status acknowledgement maps directly to the HTTP response status. With asynchronous messaging, it is assumed the target microservice has previously subscribed to the topic used for receiving commands, and the client uses a PUBLISH operation to issue the Command. The receipt status acknowledgement would typically come from a message broker to indicate whether the Command has been successfully queued for later delivery, rather than from the target microservice.

Microservice Command Interaction Pattern

Fig. 119 Microservice Command Interaction Pattern

Fig. 120 shows a typical implementation strategy for the Request-Reply Interaction Pattern using both client-server communication and asynchronous messaging. With client-server communication, sending the Request message takes the form of an HTTP GET operation, and the Reply uses the message body of the HTTP response to return the requested information. With asynchronous messaging, it is assumed the target microservice has previously subscribed to the topic used for receiving requests, and the client uses a PUBLISH operation to that topic to issue the Request. The Reply in asynchronous messaging corresponds to a PUBLISH operation performed by the microservice. The topic used for the reply is often included within the Request message contents, or is otherwise made known to the microservice prior to the Request.

Microservice Request-Reply Interaction Pattern

Fig. 120 Microservice Request-Reply Interaction Pattern

As shown in Fig. 121, the Asynchronous Status or Event Interaction Pattern is easily implemented using a PUBLISH operation with asynchronous messaging, where interested clients are assumed to have subscribed to the topic to which the Status or Event is sent. For Status messages, the topic should be configured to provide message durability to ensure delivery to at least one subscriber. With client-server communication, however, this pattern is more difficult to support and requires clients to first use a HTTP POST message to register their interest in events with the microservice. Then, when the microservice needs to send an Event or Status, it iterates to send an HTTP POST message to all interested clients.

Microservice Asynchronous Status or Event Interaction Pattern

Fig. 121 Microservice Asynchronous Status or Event Interaction Pattern