Chapter 8. API Gateway Techniques
The API Gateway is a component of API Management.
API Management takes a bigger scope than API Gateway, which means API Management is the whole process of generating and publishing APIs, while API Gateway is more like an API interface or middleware. In practice, the API Gateway works as a connector between services that are responsible to receive requests, pass them to the backend service and give a response back to consumers. Hence, the API Gateway must be able to be identified. It is also mean to be as efficient as possible to work effectively.
All of the code for the sample project in this book can be found here .
Multi Consumer management
As written in Chapter 3, one of the API Gateway uses is to control traffic. API Traffic depends on how many consumers and how many requests per each consumer. It is important to differentiate which consumer is prohibited to access your APIs, and what consumer can access that. Back to the cinema system example. Let’s say there are two third-party interfaces for a payment gateway; from bank A and bank B. Bank A can only update the transactions status of their customers that use their services, and the same with bank B. It will be troublesome if bank A is able to update transaction statuses of customers from bank B.
Versioning management
The consumers of an API will invest a significant amount of time and resources building client applications. It is important to guarantee that the API will provide its service for a long period of time without breaking the commitments undertaken with the consumer organizations. If an API is modified while client applications are using the old version, it must be verified beforehand so the new features will be able to coexist with the existing functionality.
In terms of the API Gateway itself, the benefit of using versioning is to help your system to be upgraded smoothly. Take an example of your Android native app. You have released version 2.0.0, where there is a payment feature. Then you upgraded your app having version 2.1.0 that provides push notifications about payment statuses. Say that your version 2.1.0 does not work in Android kit-kat below. If you differentiate your consumers based on versions there won’t be any problems about unnecessary data for Android kit-kat or previous versions of Android. You can always send data based on consumers’ need.
The next paragraphs detail which types of changes are backward compatible, which numbering conventions apply, and how to make Kong handle several versions of an API on the same server.
Changes that maintain backward compatibility
The following changes on an API are backward compatible:
Changes that break backward compatibility
These changes will break backward compatibility:
Major, minor and fix versions
Typically an API version will be identified with three numbers separated by a dot: MAJOR.MINOR.PATCH. The following rules explain when a new version of an API should be marked as a MAJOR change, a MINOR change, or just a PATCH:
Supporting several versions on the same gateway
Currently, Kong supports the existence of different versions of an API, provided that the version number is included in the URL:
Logging for failure or error
API Gateway allows us to store logs of requests and responses using various transports, like TCP, UDP, HTTP, and others. Log files help analyze traffic and make it easier to trace errors or fails inside the whole system. Logging for failure or error handling in the Gateway level must be done carefully, since it comes from various services and consumers.
Clear Data origin
It is important to know which services or consumers produced errors or failures. The sequences will be:
Both services and consumers have to store local log files. It helps developers trace whether error or failures happen at the gateway level, in the services level, or even at the consumers level.
Notifications for failures or errors
Besides the activity of storing local errors log, being alert about failure or error before your customer finds out is an important task. There are several plugins for traffic alerts in Kong that can be used, like Runscope for HTTP request or response.
Caching criteria
The caching process happens in-memory because there is a need to avoid querying the datastore every time. But not all requests can be cached. For example, there are available movies. Imagine your customers see the “Kong: Micro Island” movie showing at 11:45, with one available seat for her. She tries to buy a ticket, but a pop up message appears saying, “There is no seat available,” while the movies list shows that there is an available seat. This won’t be a nice experience for customers. The criteria of caching must be:
Rate limiting
Providing an API Gateway for various consumers means that your API Gateway should be available and reliable in any circumstance. There are scenarios that might happen in the API Gateway usage:
Rate limiting helps cover both scenarios in many ways.
Limit the amount of requests consumers may have
In order to protect the API Gateway from bottlenecks, it is better to prevent the requests from being made from one consumer. Here, you can set the number of allowed requests based on a period of time. It is better to decrease the number of potential unused requests. In your responsive web app, where showtime lists displayed on the frontpage and also the most frequent accessed page, you can set 60 requests per second. As for movie details, you can set 30 requests per second, as it is accessed less often.
Allocate more for higher priority requests
Which is more fatal, terminating transactions and leaving incomplete payments, or asking customer to reload their homepage?
Always put finance transactions as a higher priority than displaying processes. It is better to ask customers to reload their homepage instead of leaving an incomplete finance transaction. There is the option of using Redis or cluster. But once again you have to wisely choose which data should be using Redis or cluster since it is done in-memory.
Routing common issues
To keep your services dependent, can you do a nested API Gateway?
The answer should be an easy no . But you often fail in this option and make the API Gateway do requests for itself. The reason for not doing nested requests is the potential of an infinite loop if you don’t carefully map a request path. On the other hand, you left your API Gateway dependent on itself for results.
HTTP CORS issues
If your API Gateway makes an HTTP request to a different domain, it needs to be CORS-friendly. If you use cross domain requests, you need to add the Access-Control-Allow-Origin header to your responses in your handlers. If you’re using cookies or other authentication, you’ll also need to add the Access-Control-Allow-Credentials header to your response. But no worries, Kong has a CORS plugin so you don’t have to manually do this.
Specific-Purpose route
Is it okay to have two routes for one request in a different scenario? For example, you may have a route to display showtime lists that display price in the Euro and another route to display showtime lists that display price in USD.
If you do routes like that, it is the same as putting business logic in the frontend level. Which means, both the native Android app and responsive web app should have known where to call and when. Both of them have to detect which nationality belongs to a customer and which route should be called.
POST or GET not ANY for HTTP Requests
The basic HTTP methods for REST APIs, with no ambiguity, will be helpful for data logging. Here are those methods:
Business authorization in the API Gateway
The API Gateway may authenticate the user. But this does not mean it can always authorize users. What if a blacklist user can’t book a movie show, but can see a movie showtime? Should it be authorized in the Gateway level? A user’s scope can be very specific and it can change the core of the system. It is better to put a user’s authorization, especially business authorization for a user in the level of services. There are several options of access tokens that can be passed to services from the API Gateway like OAuth2. Chapter 10 will describe this.
Composing data in the API Gateway
In order to make responses more consumer-oriented, use transformers. Your scenarios of using a transformer might be similar to these:
  1. Collaborating two or more services respond in a single request
  2. Remove, rename, replace, add, or even append a request and/or response
Let’s say your native Android app runs in a medium screen size capable of displaying information of movie showtimes and details like casts and ratings. And say you construct your services like this:
  1. Showtime services
ID
TITLE
SHOWTIME
PRICE
Short Desc
MV-1709-001
Kong: Micro Island
12:45
$10
...
MV-1709-001
Alien: Components
13:45
$10
...
MV-1709-003
King Artie: Legend of the Swarm
21:15
$10
...
  1. Movie services
ID
TITLE
CASTS
RATINGS
RELEASE DATE
MV-1709-001
Kong: Micro Island
Brit, Tim, Sam
8
2017-09-01
MV-1709-001
Alien: Components
Ailee, Dave
7
2017-09-01
MV-1709-003
King Artie: Legend of the Swarm
Cliff, Joan
8
2017-09-01
Your Native Android app needs data like this:
ID
TITLE
SHOWTIME
PRICE
CASTS
RATINGS
MV-1709-001
Kong: Micro Island
12:45
$10
Brit, Tim, Sam
8
MV-1709-001
Alien: Components
13:45
$10
Ailee, Dave
7
MV-1709-003
King Artie: Legend of the Swarm
21:15
$10
Cliff, Joan
8
To have results like in the table above, you need to join your showtime services and movie services based on a movie ID. It can be done in the Gateway level. As you know, most of the logical functions in the Gateway level were done in-memory. Again, it costs more for the API Gateway. Besides, the API Gateway must be smart enough to handle unstructured data since the microservices architecture allows us to have various databases, like mongoDB, mySQL, Cassandra and others. The other option is applying the Command Query Responsibility Segregation (CQRS) pattern to do the composing.
Transforming API requests and responses
Let’s say you applied the CQRS Pattern and have read-only data like this:
ID
TITLE
SHOWTIME
PRICE
CASTS
RATINGS
MV-1709-001
Kong: Micro Island
12:45
$10
Brit, Tim, Sam
8
MV-1709-001
Alien: Components
13:45
$10
Ailee, Dave
7
MV-1709-003
King Artie: Legend of the Swarm
21:15
$10
Cliff, Joan
8
At the same time your cinema system is scaling up, allowing a display price based on users’ nationality, your app is available for smaller screen size so that there is no need to display ratings and casts.
ID
TITLE
SHOWTIME
PRICE
MV-1709-001
Kong: Micro Island
12:45
€8.06
MV-1709-001
Alien: Components
13:45
€8.06
MV-1709-003
King Artie: Legend of the Swarm
21:15
€8.06
Modifying responses for specific purposes are better done in the services level, since handling policies in the Gateway level could mess up the application design. Besides, you have to change all consumers’ settings if the policies have changed.
Although microservices allow every service to be deployed independently, it will be difficult if each service has a different terminology of similar things, such as pagination. For example, your showtime services with pagination may use skip and take as parameters, while your movie services use parameters like page and take . Then your API Gateway has to translate consumer’s parameters so they can be understood by services.
Doing workflow in the API Gateway
Let’s say you have a flow like this:
  1. Customer books two tickets for watching a movie in a booking service
  2. Service generates an invoice in the billing service
  3. System sends an invoice to email using a third-party mail service
It is common to have relationships between processes of different services like this sample above. But, it is better not to do it in the Gateway level. Despite the memory usage issue, it causes high dependencies between services in the Gateway level, and risks too much if one of the flows fails. Doing this in the Gateway level is much more like doing monolith scenarios in the Gateway level. There are options to do event driven processes in a microservices way that use a message broker.
Summary
You should now have a deeper understanding of the API Gateway for Kong and how to best use it. In the next chapter we’ll focus on API security.