Skip to content

Commit

Permalink
#590 explanation for API Gateway
Browse files Browse the repository at this point in the history
  • Loading branch information
iluwatar committed Jul 26, 2020
1 parent 0a35cdf commit 3e1a83e
Showing 1 changed file with 135 additions and 6 deletions.
141 changes: 135 additions & 6 deletions api-gateway/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,142 @@ folder: api-gateway
permalink: /patterns/api-gateway/
categories: Architectural
tags:
- Cloud distributed
- Decoupling
- Cloud distributed
- Decoupling
- Microservices
---

## Intent

Aggregate calls to microservices in a single location: the API Gateway. The user makes a single
call to the API Gateway, and the API Gateway then calls each relevant microservice.
Aggregate calls to microservices in a single location: the API Gateway. The user makes a single call to the API Gateway,
and the API Gateway then calls each relevant microservice.

## Explanation

With the Microservices pattern, a client may need data from multiple different microservices. If the client called each
microservice directly, that could contribute to longer load times, since the client would have to make a network request
for each microservice called. Moreover, having the client call each microservice directly ties the client to that
microservice - if the internal implementations of the microservices change (for example, if two microservices are
combined sometime in the future) or if the location (host and port) of a microservice changes, then every client that
makes use of those microservices must be updated.

The intent of the API Gateway pattern is to alleviate some of these issues. In the API Gateway pattern, an additional
entity (the API Gateway) is placed between the client and the microservices. The job of the API Gateway is to aggregate
the calls to the microservices. Rather than the client calling each microservice individually, the client calls the
API Gateway a single time. The API Gateway then calls each of the microservices that the client needs.

Real world example

> We are implementing microservices and API Gateway pattern for an e-commerce site. In this system the API Gateway makes
calls to the Image and Price microservices.

In plain words

> For a system implemented using microservices architecture, API Gateway is the single entry point that aggregates the
calls to the individual microservices.

Wikipedia says

> API Gateway is a server that acts as an API front-end, receives API requests, enforces throttling and security
policies, passes requests to the back-end service and then passes the response back to the requester. A gateway often
includes a transformation engine to orchestrate and modify the requests and responses on the fly. A gateway can also
provide functionality such as collecting analytics data and providing caching. The gateway can provide functionality to
support authentication, authorization, security, audit and regulatory compliance.

**Programmatic Example**

This implementation shows what the API Gateway pattern could look like for an e-commerce site. The `ApiGateway` makes
calls to the Image and Price microservices using the `ImageClientImpl` and `PriceClientImpl` respectively. Customers
viewing the site on a desktop device can see both price information and an image of a product, so the `ApiGateway` calls
both of the microservices and aggregates the data in the `DesktopProduct` model. However, mobile users only see price
information; they do not see a product image. For mobile users, the `ApiGateway` only retrieves price information, which
it uses to populate the `MobileProduct`.

Here's the Image microservice implementation.

```java
public interface ImageClient {
String getImagePath();
}

public class ImageClientImpl implements ImageClient {

@Override
public String getImagePath() {
var httpClient = HttpClient.newHttpClient();
var httpGet = HttpRequest.newBuilder()
.GET()
.uri(URI.create("http://localhost:50005/image-path"))
.build();

try {
var httpResponse = httpClient.send(httpGet, BodyHandlers.ofString());
return httpResponse.body();
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}

return null;
}
}
```

Here's the Price microservice implementation.

```java
public interface PriceClient {
String getPrice();
}

public class PriceClientImpl implements PriceClient {

@Override
public String getPrice() {
var httpClient = HttpClient.newHttpClient();
var httpGet = HttpRequest.newBuilder()
.GET()
.uri(URI.create("http://localhost:50006/price"))
.build();

try {
var httpResponse = httpClient.send(httpGet, BodyHandlers.ofString());
return httpResponse.body();
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}

return null;
}
}
```

And here we can see how API Gateway maps the requests to the microservices.

```java
public class ApiGateway {

@Resource
private ImageClient imageClient;

@Resource
private PriceClient priceClient;

@RequestMapping(path = "/desktop", method = RequestMethod.GET)
public DesktopProduct getProductDesktop() {
var desktopProduct = new DesktopProduct();
desktopProduct.setImagePath(imageClient.getImagePath());
desktopProduct.setPrice(priceClient.getPrice());
return desktopProduct;
}

@RequestMapping(path = "/mobile", method = RequestMethod.GET)
public MobileProduct getProductMobile() {
var mobileProduct = new MobileProduct();
mobileProduct.setPrice(priceClient.getPrice());
return mobileProduct;
}
}
```

## Class diagram
![alt text](./etc/api-gateway.png "API Gateway")
Expand All @@ -21,10 +149,11 @@ call to the API Gateway, and the API Gateway then calls each relevant microservi

Use the API Gateway pattern when

* you're also using the Microservices pattern and need a single point of aggregation for your
microservice calls
* You're using microservices architecture and need a single point of aggregation for your microservice calls.

## Credits

* [microservices.io - API Gateway](http://microservices.io/patterns/apigateway.html)
* [NGINX - Building Microservices: Using an API Gateway](https://www.nginx.com/blog/building-microservices-using-an-api-gateway/)
* [Microservices Patterns: With examples in Java](https://www.amazon.com/gp/product/1617294543/ref=as_li_qf_asin_il_tl?ie=UTF8&tag=javadesignpat-20&creative=9325&linkCode=as2&creativeASIN=1617294543&linkId=ac7b6a57f866ac006a309d9086e8cfbd)
* [Building Microservices: Designing Fine-Grained Systems](https://www.amazon.com/gp/product/1491950358/ref=as_li_qf_asin_il_tl?ie=UTF8&tag=javadesignpat-20&creative=9325&linkCode=as2&creativeASIN=1491950358&linkId=4c95ca9831e05e3f0dadb08841d77bf1)

0 comments on commit 3e1a83e

Please sign in to comment.