API Gateways and Service Networks

Today we will talk about one of the key components in microservices and web application architectures – API gateways. These gateways are a centralized entry point for managing client requests and redirecting them to the appropriate microservices or internal services within the target system.

Essentially, API Gateway is a service that sits between the application clients on one side and the backend components on the other, acting as a reverse proxy to accept incoming requests from clients, perform various operations such as routing, authentication, and rate limiting, and then forward those requests to the appropriate backend services.

Thus, the role of an API gateway in a software architecture is to sit in front of the implementation components and provide the necessary services.

Services provided

If we talk in more detail about the services in question, these are primarily authentication and authorization services – those services that are responsible for managing access to the service in front of which the gateway stands. In fact, various mechanisms can be used to implement this functionality, such as passwords, certificates, or two-factor authentication. Integration with services such as a firewall is also possible.

Another purpose of the services provided by API services is to protect the components of the target application from load surges. Thus, when configured correctly, the API gateway becomes the only way for clients to access the service. Therefore, the load regulation mechanisms implemented here can provide significant protection.

Returning to access control issues, it is worth noting that services that are part of API gateways can also maintain access logs, since all traffic to the service goes through the gateway and we have the ability to log all access.

An API gateway can perform its functions by interacting with many other services. For example, the gateway itself does not store data about users who need to be authenticated and authorized. It relies on a solution that implements identity management and access to account stores (e.g., LDAP) for these services, but the gateway itself simply enforces the policy stated there.

As an example, consider a simple scenario where an API gateway sits in front of a couple of services, all access to those services is through that gateway, and it interacts with other components to support the functionality it offers.

The problem with the API gateway configuration shown in the figure is that it is a single entry point and, accordingly, a single point of failure. For modern high-performance systems, such a solution is hardly acceptable.

Obviously, in practice we will have several instances of each service, including the gateway service itself. A good development of this solution is to embed the gateway into the service. Such an implementation provides some obvious advantages: there is no transit network section between the gateway and the service itself, which in turn could cause possible problems when transmitting traffic between services.

Also, we no longer need a host name for configuration, but only a path for connection. But there are a number of difficulties that need to be dealt with.

In fact, we need to embed our API gateway into the target services.

As an example, consider the Netflix Zuul solution, which is part of the Netflix Spring Cloud project, designed to provide dynamic routing, monitoring, security solutions, and other functionality for microservice applications.

Zuul is usually described as a classic gateway based on a servlet stack, operating on the principle of one request – one thread.

Zuul is written in Java and obviously runs in a Java virtual machine. This gateway uses a URL to interact with services. For example, to configure it as a gateway for an abstract Service, you would provide the following configuration data:

zuul.routes.connectionService.url=http://localhost:8090/connectionPosts

server.port=8080

The question then becomes how to incorporate Zuul into our software topology. In a highly distributed architecture, it is recommended to use a variant similar to the one shown in the figure.

In the case of Zuul, we can leverage Spring Cloud functionality to integrate into your service.

However, when using a gateway written in Java, we find ourselves in some dependence on this programming language, since it turns out that the rest of the service components must also be written in this language.

Also, one of the goals of the API Gateway pattern is to separate the interests of the service developer from the interests of the service operator. You want to enable operators to apply consistent controls to all running services and offer them a control plane that makes this process manageable.

How then can we achieve something like this gateway pattern in a way that is language independent, more loosely coupled, and more manageable? This is where service meshes come in.

Istio Service Meshes

To avoid the drawbacks of an embedded component, we use Sidecars. In the image below, we can see a group of Envoy proxies connected via channels that will handle the communication between them. It looks like a mesh; hence the name. A service mesh spans a set of interconnected sidecars and adds a management layer to manage these proxies.

One of the most widely used service meshes available today belongs to Istiowhich allows you to extend the functionality of Kubernetes through the use of Envoy modules.

The presented architecture is an important pattern for protecting a service from excessive load, including traffic caused by a barrage of repeated requests. The presented patterns, applied on both the client and service sides of the interaction, can be encapsulated and deployed as a proxy server using a sidecar.

The service mesh gives this proxy an additional control plane that allows the operator to control security, provide observability, and allow configuration of the set of services/applications that make up the cloud software.

Conclusion

In this article, we looked at one of the patterns designed to be placed on the front edge of a service to ensure that the service is protected from various load surges. Using this pattern allows you to increase the security and manageability of your application in a cloud environment.

Today (September 16) at 20:00 there will be an open lesson “Practical Guide to Applying SOLID Principles”. In it we will master the algorithm for applying SOLID principles to create flexible and easily extensible code.

If it's relevant, hurry up to sign up for a lesson. on the Architecture and Design Patterns course page.

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *