First of all, I would like to affirm that an API gateway can be built in almost any programming language, and it will not define or require any specific language in the microservices connected to it, so keep in mind that you can pick the language that makes more sense in your context and your necessities.
I will not focus on the microservices architecture in this article. I will suppose that you already know a little about it. You want to expand your knowledge about this amazing subject. Besides that, I will use just synchronous calls to explain it (what makes things clearer).
Before I detail the API Gateway, I would like to introduce an imaginary situation where we do not implement it to see this approach's problems.
Let's imagine that we have a client that is a Web App (client/front-end) that integrates with 2 microservices (services/back-end):
Now, imagine that both services are called when one specific action is performed. It depends on the two services to conclude the whole functionality.
If you are not used to this scenario, It can look perfect and quite simple; however, it is not. You will start having trouble when it goes to production.
Security: In this scenario, all the services are exposed publically to the world so that everyone can access them, and consequently, everyone can try to hack them. You will have loads of APIs to manage and to worry about.
The latency: Imagine a client calling many different APIs and waiting for their responses, it would be a big problem, and you can have a timeout and even usability problems (what increase the perception of a bad product by your users).
Coupling and duplicated code: That is a huge drawback. Imagine that you will have to put the logic necessary for calling direct all the microservices (with loads of different URLs), and besides that, aggregate all the information. It will create a mass when you start introducing new microservices, or even when you need to implement it in a different client (Apps, Web Apps…).
Authentication / Authorization: It must be done in each of the microservices, which makes the process not very efficient for new microservices that could show up in the future, and either for the maintenance of the existing ones. Introducing the API Gateway
The API Gateway works as such a Middleware between your clients and your services. It is right in the middle, and it is used to centralize the external calls. It brings a lot of advantages over the previous example (when working with microservices).
I mentioned four drawbacks of the previous approach, and now I will show you how the API Gateway solves these problems, and it brings more benefits for your application as a whole.
Security: Unlike the previous example, now we can restrict the external access to our microservices through a private network that will be visible on for the Gateway. It makes your application much more secure against hacker attacks, and it is not necessary to code it. It is just a configuration network.
The latency: As all the services will be in the same network, what makes things faster. Your clients will have to call only one API (the gateway).
Coupling and duplicated code: All the logic and aggregations will be self-contained on the gateway, so we do not need to worry about adding any unnecessary complexity in the wrong place (front-end). Besides that, we can change our APIs and endpoints easily, and if we don't break the interface of our actions, all the changes (tiny or huge) will be irrelevant for the clients.
Authentication / Authorization: It can be centralized in the gateway, or even better, you can implement a specific service for doing that. The API Gateway will consume this service.
The diagram below shows the detail.
Step 1 — The client sends an HTTP request to the API gateway.
Step 2 — The API gateway parses and validates the attributes in the HTTP request.
Step 3 — The API gateway performs allow-list/deny-list checks.
Step 4 — The API gateway talks to an identity provider for authentication and authorization.
Step 5 — The rate limiting rules are applied to the request. If it is over the limit, the request is rejected.
Steps 6 and 7 — Now that the request has passed basic checks, the API gateway finds the relevant service to route to by path matching.
Step 8 — The API gateway transforms the request into the appropriate protocol and sends it to backend microservices.
Steps 9–12: The API gateway can handle errors properly, and deals with faults if the error takes a longer time to recover (circuit break). It can also leverage ELK (Elastic-Logstash-Kibana) stack for logging and monitoring. We sometimes cache data in the API gateway.