Skip to content

Commit 0ad9937

Browse files
committed
Merge pull request #427 from surgeforward/297
#297 Create API Gateway pattern
2 parents 71e3443 + f234a68 commit 0ad9937

30 files changed

Lines changed: 1273 additions & 0 deletions

File tree

api-gateway/README.md

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
---
2+
layout: pattern
3+
title: API Gateway
4+
folder: api-gateway
5+
permalink: /patterns/api-gateway/
6+
categories: Architectural
7+
tags:
8+
- Java
9+
- Difficulty-Intermediate
10+
- Spring
11+
---
12+
13+
## Intent
14+
15+
Aggregate calls to microservices in a single location: the API Gateway. The user makes a single
16+
call to the API Gateway, and the API Gateway then calls each relevant microservice.
17+
18+
![alt text](./etc/api-gateway.png "API Gateway")
19+
20+
## Applicability
21+
22+
Use the API Gateway pattern when
23+
24+
* you're also using the Microservices pattern and need a single point of aggregation for your
25+
microservice calls
26+
27+
## Credits
28+
29+
* [microservices.io - API Gateway](http://microservices.io/patterns/apigateway.html)
30+
* [NGINX - Building Microservices: Using an API Gateway](https://www.nginx.com/blog/building-microservices-using-an-api-gateway/)
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
4+
The MIT License
5+
Copyright (c) 2014 Ilkka Seppälä
6+
7+
Permission is hereby granted, free of charge, to any person obtaining a copy
8+
of this software and associated documentation files (the "Software"), to deal
9+
in the Software without restriction, including without limitation the rights
10+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11+
copies of the Software, and to permit persons to whom the Software is
12+
furnished to do so, subject to the following conditions:
13+
14+
The above copyright notice and this permission notice shall be included in
15+
all copies or substantial portions of the Software.
16+
17+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23+
THE SOFTWARE.
24+
25+
-->
26+
<project xmlns="http://maven.apache.org/POM/4.0.0"
27+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
28+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
29+
<parent>
30+
<artifactId>api-gateway</artifactId>
31+
<groupId>com.iluwatar</groupId>
32+
<version>1.12.0-SNAPSHOT</version>
33+
</parent>
34+
<modelVersion>4.0.0</modelVersion>
35+
<artifactId>api-gateway-service</artifactId>
36+
<packaging>jar</packaging>
37+
38+
<dependencyManagement>
39+
<dependencies>
40+
<dependency>
41+
<groupId>org.springframework.boot</groupId>
42+
<artifactId>spring-boot-dependencies</artifactId>
43+
</dependency>
44+
</dependencies>
45+
</dependencyManagement>
46+
<dependencies>
47+
<dependency>
48+
<groupId>org.springframework</groupId>
49+
<artifactId>spring-webmvc</artifactId>
50+
</dependency>
51+
<dependency>
52+
<groupId>org.springframework.boot</groupId>
53+
<artifactId>spring-boot-starter-web</artifactId>
54+
</dependency>
55+
<dependency>
56+
<groupId>junit</groupId>
57+
<artifactId>junit</artifactId>
58+
<scope>test</scope>
59+
</dependency>
60+
<dependency>
61+
<groupId>org.mockito</groupId>
62+
<artifactId>mockito-core</artifactId>
63+
<scope>test</scope>
64+
</dependency>
65+
<dependency>
66+
<groupId>org.apache.httpcomponents</groupId>
67+
<artifactId>httpclient</artifactId>
68+
</dependency>
69+
</dependencies>
70+
71+
<build>
72+
<plugins>
73+
<plugin>
74+
<groupId>org.springframework.boot</groupId>
75+
<artifactId>spring-boot-maven-plugin</artifactId>
76+
<version>${spring-boot.version}</version>
77+
<executions>
78+
<execution>
79+
<goals>
80+
<goal>repackage</goal>
81+
</goals>
82+
</execution>
83+
</executions>
84+
</plugin>
85+
</plugins>
86+
</build>
87+
</project>
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
/**
2+
* The MIT License
3+
* Copyright (c) 2014 Ilkka Seppälä
4+
*
5+
* Permission is hereby granted, free of charge, to any person obtaining a copy
6+
* of this software and associated documentation files (the "Software"), to deal
7+
* in the Software without restriction, including without limitation the rights
8+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
* copies of the Software, and to permit persons to whom the Software is
10+
* furnished to do so, subject to the following conditions:
11+
*
12+
* The above copyright notice and this permission notice shall be included in
13+
* all copies or substantial portions of the Software.
14+
*
15+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21+
* THE SOFTWARE.
22+
*/
23+
package com.iluwatar.api.gateway;
24+
25+
import org.springframework.web.bind.annotation.RequestMapping;
26+
import org.springframework.web.bind.annotation.RestController;
27+
28+
import javax.annotation.Resource;
29+
30+
/**
31+
* The ApiGateway aggregates calls to microservices based on the needs of the individual clients.
32+
*/
33+
@RestController
34+
public class ApiGateway {
35+
36+
@Resource
37+
private ImageClient imageClient;
38+
39+
@Resource
40+
private PriceClient priceClient;
41+
42+
/**
43+
* Retrieves product information that desktop clients need
44+
* @return Product information for clients on a desktop
45+
*/
46+
@RequestMapping("/desktop")
47+
public DesktopProduct getProductDesktop() {
48+
DesktopProduct desktopProduct = new DesktopProduct();
49+
desktopProduct.setImagePath(imageClient.getImagePath());
50+
desktopProduct.setPrice(priceClient.getPrice());
51+
return desktopProduct;
52+
}
53+
54+
/**
55+
* Retrieves product information that mobile clients need
56+
* @return Product information for clients on a mobile device
57+
*/
58+
@RequestMapping("/mobile")
59+
public MobileProduct getProductMobile() {
60+
MobileProduct mobileProduct = new MobileProduct();
61+
mobileProduct.setPrice(priceClient.getPrice());
62+
return mobileProduct;
63+
}
64+
}
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
/**
2+
* The MIT License
3+
* Copyright (c) 2014 Ilkka Seppälä
4+
*
5+
* Permission is hereby granted, free of charge, to any person obtaining a copy
6+
* of this software and associated documentation files (the "Software"), to deal
7+
* in the Software without restriction, including without limitation the rights
8+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
* copies of the Software, and to permit persons to whom the Software is
10+
* furnished to do so, subject to the following conditions:
11+
*
12+
* The above copyright notice and this permission notice shall be included in
13+
* all copies or substantial portions of the Software.
14+
*
15+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21+
* THE SOFTWARE.
22+
*/
23+
package com.iluwatar.api.gateway;
24+
25+
import org.springframework.boot.SpringApplication;
26+
import org.springframework.boot.autoconfigure.SpringBootApplication;
27+
28+
/**
29+
* With the Microservices pattern, a client may need data from multiple different microservices.
30+
* If the client called each microservice directly, that could contribute to longer load times,
31+
* since the client would have to make a network request for each microservice called. Moreover,
32+
* having the client call each microservice directly ties the client to that microservice - if the
33+
* internal implementations of the microservices change (for example, if two microservices are
34+
* combined sometime in the future) or if the location (host and port) of a microservice changes,
35+
* then every client that makes use of those microservices must be updated.
36+
*
37+
* <p>
38+
* The intent of the API Gateway pattern is to alleviate some of these issues. In the API Gateway
39+
* pattern, an additional entity (the API Gateway) is placed between the client and the
40+
* microservices. The job of the API Gateway is to aggregate the calls to the microservices.
41+
* Rather than the client calling each microservice individually, the client calls the API Gateway
42+
* a single time. The API Gateway then calls each of the microservices that the client needs.
43+
*
44+
* <p>
45+
* This implementation shows what the API Gateway pattern could look like for an e-commerce site.
46+
* The {@link ApiGateway} makes calls to the Image and Price microservices using the
47+
* {@link ImageClientImpl} and {@link PriceClientImpl} respectively. Customers viewing the site on a
48+
* desktop device can see both price information and an image of a product, so the {@link ApiGateway}
49+
* calls both of the microservices and aggregates the data in the {@link DesktopProduct} model.
50+
* However, mobile users only see price information; they do not see a product image. For mobile
51+
* users, the {@link ApiGateway} only retrieves price information, which it uses to populate the
52+
* {@link MobileProduct}.
53+
*/
54+
@SpringBootApplication
55+
public class App {
56+
57+
/**
58+
* Program entry point
59+
*
60+
* @param args
61+
* command line args
62+
*/
63+
public static void main(String[] args) {
64+
SpringApplication.run(App.class, args);
65+
}
66+
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/**
2+
* The MIT License
3+
* Copyright (c) 2014 Ilkka Seppälä
4+
*
5+
* Permission is hereby granted, free of charge, to any person obtaining a copy
6+
* of this software and associated documentation files (the "Software"), to deal
7+
* in the Software without restriction, including without limitation the rights
8+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
* copies of the Software, and to permit persons to whom the Software is
10+
* furnished to do so, subject to the following conditions:
11+
*
12+
* The above copyright notice and this permission notice shall be included in
13+
* all copies or substantial portions of the Software.
14+
*
15+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21+
* THE SOFTWARE.
22+
*/
23+
package com.iluwatar.api.gateway;
24+
25+
/**
26+
* Encapsulates all of the information that a desktop client needs to display a product.
27+
*/
28+
public class DesktopProduct {
29+
/**
30+
* The price of the product
31+
*/
32+
private String price;
33+
34+
/**
35+
* The path to the image of the product
36+
*/
37+
private String imagePath;
38+
39+
public String getPrice() {
40+
return price;
41+
}
42+
43+
public void setPrice(String price) {
44+
this.price = price;
45+
}
46+
47+
public String getImagePath() {
48+
return imagePath;
49+
}
50+
51+
public void setImagePath(String imagePath) {
52+
this.imagePath = imagePath;
53+
}
54+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/**
2+
* The MIT License
3+
* Copyright (c) 2014 Ilkka Seppälä
4+
*
5+
* Permission is hereby granted, free of charge, to any person obtaining a copy
6+
* of this software and associated documentation files (the "Software"), to deal
7+
* in the Software without restriction, including without limitation the rights
8+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
* copies of the Software, and to permit persons to whom the Software is
10+
* furnished to do so, subject to the following conditions:
11+
*
12+
* The above copyright notice and this permission notice shall be included in
13+
* all copies or substantial portions of the Software.
14+
*
15+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21+
* THE SOFTWARE.
22+
*/
23+
package com.iluwatar.api.gateway;
24+
25+
/**
26+
* An interface used to communicate with the Image microservice
27+
*/
28+
public interface ImageClient {
29+
String getImagePath();
30+
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/**
2+
* The MIT License
3+
* Copyright (c) 2014 Ilkka Seppälä
4+
*
5+
* Permission is hereby granted, free of charge, to any person obtaining a copy
6+
* of this software and associated documentation files (the "Software"), to deal
7+
* in the Software without restriction, including without limitation the rights
8+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
* copies of the Software, and to permit persons to whom the Software is
10+
* furnished to do so, subject to the following conditions:
11+
*
12+
* The above copyright notice and this permission notice shall be included in
13+
* all copies or substantial portions of the Software.
14+
*
15+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21+
* THE SOFTWARE.
22+
*/
23+
package com.iluwatar.api.gateway;
24+
25+
import org.apache.http.client.methods.CloseableHttpResponse;
26+
import org.apache.http.client.methods.HttpGet;
27+
import org.apache.http.impl.client.CloseableHttpClient;
28+
import org.apache.http.impl.client.HttpClients;
29+
import org.apache.http.util.EntityUtils;
30+
import org.springframework.stereotype.Component;
31+
32+
import java.io.IOException;
33+
34+
/**
35+
* An adapter to communicate with the Image microservice
36+
*/
37+
@Component
38+
public class ImageClientImpl implements ImageClient{
39+
/**
40+
* Makes a simple HTTP Get request to the Image microservice
41+
* @return The path to the image
42+
*/
43+
@Override
44+
public String getImagePath() {
45+
String response = null;
46+
try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
47+
HttpGet httpGet = new HttpGet("http://localhost:50005/image-path");
48+
try (CloseableHttpResponse httpResponse = httpClient.execute(httpGet)) {
49+
response = EntityUtils.toString(httpResponse.getEntity());
50+
}
51+
} catch (IOException e) {
52+
e.printStackTrace();
53+
}
54+
return response;
55+
}
56+
}

0 commit comments

Comments
 (0)