The fifth day’s post of Mercari Advent Calendar 2020 is brought to you by Shiva Chaitanya from the Mercari Backend team.
What and Why of microservices ?
Hey there, can I know which is your favourite app that you have been using quite-a-lot recently ?
Maybe it is a social-media app / informative app / any other app, have you wondered what minimum components are needed for running an application / app ? Today, let’s understand what happens behind the scenes, in a high-level view.
There are two major things to note,
- Web Frontend / Mobile App -> To display/fetch data to/from users.
- Backend -> To process/store data from users.
In the below illustration, the frontend sends a request to the backend, it may be for user-login / likes / notifications / etc…. Each and every request will be sent to a single backend component / service. This backend service will do some appropriate actions and send back data to the frontend.
This type of design / architecture is well suited for small applications. But when the application size grows, then it is difficult to handle in one service. In such cases, it is better to divide one component into smaller components. These smaller components are called microservices.
Now, each microservice can handle requests for each use-case, in our example, login, likes, notification.
We can see that, if more number of microservices come in, there can be few problems,as;
- The frontend has to know multiple backend service addresses.
- Communication between microservices will be challenging and complex, with-respect-to aspects like authorization, authentication of microservices.
For example, if there are new likes for a post, then likes service has to communicate with notification service for notifying the users.
To overcome this problem, we use;
- A service which maps / redirects a request from frontend to corresponding backend service.
- Can handle authorization of each request.
- Can be used for token generation. Token can be used for user authentication.
- Establishing communication between microservices.
In the above illustration, we can use gateway to authorize likes service to communicate with notification service.
Friend, now you know what a microservice is. Great, but Guy Kawasaki says, “Ideas are easy, implementation is hard”.
so, let’s take a look at the little hard part.
Basics of implementing microservices:
The first step in building microservices is knowing / defining what each microservice does, those are called Interfaces.
In our example above, Likes microservice provides two functionalities,
- Giving a Like to someone’s post.
- Retrieving total number of likes for a post.
When you hit a Like button, that request will be sent to Likes microservice, GiveALike endpoint. We need not know how it implements internally, but we need to know what parameters it takes as input. GiveALike endpoint takes postID as an input, in the above example it returns if the operation is successful or not.
Similarly, when we want to know the total number of Likes for a post, a request will be sent to Likes microservice, GetNumOfLikes endpoint, here input parameter will be postID and returns the total number of likes for a post.
postID can be an unique identifier for a post made by a user, on any social media platforms.
Communication between microservices:
As microservices don’t need extra payload [like some header fields] like in HTTP based communication, they can communicate through gRPC protocol.
A protocol means a standard mechanism for communications. With gRPC based communications, we can define our own messages for each microservice.
In HTTP communication: 200 status code is success, this is fixed.
In gRPC communication: we can use any code to communicate between microservices.
My example is for easy-understand, but please note that
- For any HTTP communication in the world between computers / services, mostly 200 status code is used, but in gRPC we can use agreed constant between two services.
- There are fixed status codes in gRPC also.
To define the message format and communications for a microservice, we can use proto definitions.
An example proto file for Likes microservice which has required interfaces and messages for communication.
Implementation of interfaces:
The next step is writing logic for the interfaces, on how you want to implement them. This can be written in your favourite language, some server-side programming language examples are Golang, Java, etc.
From the above illustration, we need to implement logic step-by-step as,
- When a user X likes a post from User Y, it will be sent for processing.
- Gateway will choose to redirect the request to Likes microservice.
- Likes microservice will store the corresponding data to it’s own database.
- Likes microservice will initiate a call to notification service to send a notification to User Y.
- Notification microservice will store corresponding data into it’s database after confirming the request is legitimate.
- Response will be sent back to gateway to intimate user Y.
- User Y will get a notification in their application.
After defining interfaces and their implementation for each microservice, we can create docker images for each microservice and deploy in favourite environments, like in Google cloud, AWS, etc.
This blog tried to focus on the very basics of what and why microservices, so deployment related detail is kept out-of-scope as it is little advanced.
We reached the end, how does that feel ? Easy ? Good ? Overwhelming ? The answer can be anything, it’s ok. The happy part is, now you know what it looks like behind the scenes to get a notification. Next time when you hear the notification chime on your phone, it is microservices, my friend.
Mercari is looking for software engineers who share our mission and values.
Tomorrow’s blog post —the sixth in the Advent Calendar— will be written by Kodai NAKAMURA. Hope you are looking forward to it!