From 88c3b04eb38441867ed4de7fb71048d0bbc52da9 Mon Sep 17 00:00:00 2001 From: tmcconville Date: Sun, 7 Feb 2016 17:05:33 -0600 Subject: [PATCH] #297 Create API Gateway pattern --- api-gateway/pom.xml | 19 ++++++++ .../com/iluwatar/api/gateway/ApiGateway.java | 31 +++++++++++++ .../java/com/iluwatar/api/gateway/App.java | 46 +++++++++++++++++++ .../iluwatar/api/gateway/DesktopProduct.java | 26 +++++++++++ .../iluwatar/api/gateway/ImageService.java | 15 ++++++ .../iluwatar/api/gateway/MobileProduct.java | 17 +++++++ .../iluwatar/api/gateway/PriceService.java | 15 ++++++ pom.xml | 1 + 8 files changed, 170 insertions(+) create mode 100644 api-gateway/pom.xml create mode 100644 api-gateway/src/main/java/com/iluwatar/api/gateway/ApiGateway.java create mode 100644 api-gateway/src/main/java/com/iluwatar/api/gateway/App.java create mode 100644 api-gateway/src/main/java/com/iluwatar/api/gateway/DesktopProduct.java create mode 100644 api-gateway/src/main/java/com/iluwatar/api/gateway/ImageService.java create mode 100644 api-gateway/src/main/java/com/iluwatar/api/gateway/MobileProduct.java create mode 100644 api-gateway/src/main/java/com/iluwatar/api/gateway/PriceService.java diff --git a/api-gateway/pom.xml b/api-gateway/pom.xml new file mode 100644 index 000000000..bb7f5701d --- /dev/null +++ b/api-gateway/pom.xml @@ -0,0 +1,19 @@ + + + + java-design-patterns + com.iluwatar + 1.10.0-SNAPSHOT + + 4.0.0 + api-gateway + + + junit + junit + test + + + \ No newline at end of file diff --git a/api-gateway/src/main/java/com/iluwatar/api/gateway/ApiGateway.java b/api-gateway/src/main/java/com/iluwatar/api/gateway/ApiGateway.java new file mode 100644 index 000000000..0ecbf7405 --- /dev/null +++ b/api-gateway/src/main/java/com/iluwatar/api/gateway/ApiGateway.java @@ -0,0 +1,31 @@ +package com.iluwatar.api.gateway; + +/** + * The ApiGateway aggregates calls to microservices based on the needs of the individual clients. + */ +public class ApiGateway { + + private ImageService imageService = new ImageService(); + private PriceService priceService = new PriceService(); + + /** + * Retrieves product information that desktop clients need + * @return Product information for clients on a desktop + */ + public DesktopProduct getProductDesktop() { + DesktopProduct desktopProduct = new DesktopProduct(); + desktopProduct.setImagePath(imageService.getImagePath()); + desktopProduct.setPrice(priceService.getPrice()); + return desktopProduct; + } + + /** + * Retrieves product information that mobile clients need + * @return Product information for clients on a mobile device + */ + public MobileProduct getProductMobile() { + MobileProduct mobileProduct = new MobileProduct(); + mobileProduct.setPrice(priceService.getPrice()); + return mobileProduct; + } +} diff --git a/api-gateway/src/main/java/com/iluwatar/api/gateway/App.java b/api-gateway/src/main/java/com/iluwatar/api/gateway/App.java new file mode 100644 index 000000000..7bad0269b --- /dev/null +++ b/api-gateway/src/main/java/com/iluwatar/api/gateway/App.java @@ -0,0 +1,46 @@ +package com.iluwatar.api.gateway; + +/** + * 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. + * + *

+ * This implementation shows what the API Gateway pattern could look like for an e-commerce site. + * In this case, the (@link ImageService) and (@link PriceService) represent our microservices. + * Customers viewing the site on a desktop device can see both price information and an image of + * a product, so the (@link ApiGateway) calls both of the microservices and aggregates the data in + * the (@link DesktopProduct) model. However, mobile users only see price information; they do not + * see a product image. For mobile users, the (@link ApiGateway) only retrieves price information, + * which it uses to populate the (@link MobileProduct). + */ +public class App { + + /** + * Program entry point + * + * @param args + * command line args + */ + public static void main(String[] args) { + ApiGateway apiGateway = new ApiGateway(); + + DesktopProduct desktopProduct = apiGateway.getProductDesktop(); + System.out.println(String.format("Desktop Product \nPrice: %s\nImage path: %s", + desktopProduct.getPrice(), desktopProduct.getImagePath())); + + MobileProduct mobileProduct = apiGateway.getProductMobile(); + System.out.println(String.format("Mobile Product \nPrice: %s", mobileProduct.getPrice())); + } +} diff --git a/api-gateway/src/main/java/com/iluwatar/api/gateway/DesktopProduct.java b/api-gateway/src/main/java/com/iluwatar/api/gateway/DesktopProduct.java new file mode 100644 index 000000000..8105b01b1 --- /dev/null +++ b/api-gateway/src/main/java/com/iluwatar/api/gateway/DesktopProduct.java @@ -0,0 +1,26 @@ +package com.iluwatar.api.gateway; + +/** + * Encapsulates all of the information that a desktop client needs to display a product. + */ +public class DesktopProduct { + + private String price; + private String imagePath; + + public String getPrice() { + return price; + } + + public void setPrice(String price) { + this.price = price; + } + + public String getImagePath() { + return imagePath; + } + + public void setImagePath(String imagePath) { + this.imagePath = imagePath; + } +} diff --git a/api-gateway/src/main/java/com/iluwatar/api/gateway/ImageService.java b/api-gateway/src/main/java/com/iluwatar/api/gateway/ImageService.java new file mode 100644 index 000000000..3904f545d --- /dev/null +++ b/api-gateway/src/main/java/com/iluwatar/api/gateway/ImageService.java @@ -0,0 +1,15 @@ +package com.iluwatar.api.gateway; + +/** + * Represents a microservice used to retrieve image data. + */ +public class ImageService { + + /** + * Gets the image path + * @return the image path + */ + public String getImagePath() { + return "/product-image.png"; + } +} diff --git a/api-gateway/src/main/java/com/iluwatar/api/gateway/MobileProduct.java b/api-gateway/src/main/java/com/iluwatar/api/gateway/MobileProduct.java new file mode 100644 index 000000000..772e540df --- /dev/null +++ b/api-gateway/src/main/java/com/iluwatar/api/gateway/MobileProduct.java @@ -0,0 +1,17 @@ +package com.iluwatar.api.gateway; + +/** + * Encapsulates all of the information that mobile client needs to display a product. + */ +public class MobileProduct { + + private String price; + + public String getPrice() { + return price; + } + + public void setPrice(String price) { + this.price = price; + } +} diff --git a/api-gateway/src/main/java/com/iluwatar/api/gateway/PriceService.java b/api-gateway/src/main/java/com/iluwatar/api/gateway/PriceService.java new file mode 100644 index 000000000..f64f1cb11 --- /dev/null +++ b/api-gateway/src/main/java/com/iluwatar/api/gateway/PriceService.java @@ -0,0 +1,15 @@ +package com.iluwatar.api.gateway; + +/** + * Represents a microservice used to retrieve price data. + */ +public class PriceService { + + /** + * Gets the price + * @return the price + */ + public String getPrice() { + return "20"; + } +} diff --git a/pom.xml b/pom.xml index d2b02fdf7..732193893 100644 --- a/pom.xml +++ b/pom.xml @@ -93,6 +93,7 @@ publish-subscribe delegation event-driven-architecture + api-gateway