From fe779cc93b64f2873320cf19f9a563b58210c4b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Sun, 26 May 2024 09:29:54 +0300 Subject: [PATCH] docs: update gateway --- gateway/README.md | 154 ++++++++++++++++++++++------------------------ 1 file changed, 73 insertions(+), 81 deletions(-) diff --git a/gateway/README.md b/gateway/README.md index d1a215e10..0440c2714 100644 --- a/gateway/README.md +++ b/gateway/README.md @@ -21,7 +21,7 @@ The Gateway design pattern aims to encapsulate the interaction with a remote ser Real-world example -> Gateway acts like a real front gate of a certain city. The people inside the city are called internal system, and different outside cities are called external services. The gateway is here to provide access for internal system to different external services. +> Consider a logistics company that uses multiple third-party services for various operations, such as shipping, inventory management, and customer notifications. Each of these services has its own API with different protocols and data formats. To simplify the interaction, the company implements a Gateway design pattern. This gateway acts as a unified interface for all third-party service interactions, allowing the company's internal systems to communicate with these services seamlessly. The gateway handles the translation of protocols, data transformation, and routing of requests, ensuring that the internal systems remain decoupled from the specifics of each external service. This setup improves maintainability and scalability while providing a single point of control for external communications. In plain words @@ -33,112 +33,105 @@ Wikipedia says **Programmatic Example** -The main class in our example is the `ExternalService` that contains items. +First, we define a `Gateway` interface. This interface represents the contract for our external services. Each service that we want to interact with will implement this interface. ```java -class ExternalServiceA implements Gateway { - @Override - public void execute() throws Exception { - LOGGER.info("Executing Service A"); - // Simulate a time-consuming task - Thread.sleep(1000); - } -} - -/** - * ExternalServiceB is one of external services. - */ -class ExternalServiceB implements Gateway { - @Override - public void execute() throws Exception { - LOGGER.info("Executing Service B"); - // Simulate a time-consuming task - Thread.sleep(1000); - } -} - -/** - * ExternalServiceC is one of external services. - */ -class ExternalServiceC implements Gateway { - @Override - public void execute() throws Exception { - LOGGER.info("Executing Service C"); - // Simulate a time-consuming task - Thread.sleep(1000); - } - - public void error() throws Exception { - // Simulate an exception - throw new RuntimeException("Service C encountered an error"); - } +public interface Gateway { + void execute(); } ``` -To operate these external services, Here's the `App` class: +Next, we create our external services. These are the services that our application needs to interact with. Each service implements the `Gateway` interface and provides its own implementation of the `execute` method. + +```java +public class ExternalServiceA implements Gateway { + @Override + public void execute() { + // Implementation for ExternalServiceA + } +} + +public class ExternalServiceB implements Gateway { + @Override + public void execute() { + // Implementation for ExternalServiceB + } +} + +public class ExternalServiceC implements Gateway { + @Override + public void execute() { + // Implementation for ExternalServiceC + } +} +``` + +We then create a `GatewayFactory` class. This class maintains a registry of all available gateways. It provides methods to register a new gateway and to retrieve a gateway by its key. + +```java +public class GatewayFactory { + private Map gateways = new HashMap<>(); + + public void registerGateway(String key, Gateway gateway) { + gateways.put(key, gateway); + } + + public Gateway getGateway(String key) { + return gateways.get(key); + } +} +``` + +Finally, we have our main application. The application uses the `GatewayFactory` to register and retrieve gateways. It then uses these gateways to interact with the external services. ```java public class App { - /** - * Simulate an application calling external services. - */ - public static void main(String[] args) throws Exception { - GatewayFactory gatewayFactory = new GatewayFactory(); + public static void main(String[] args) throws Exception { + GatewayFactory gatewayFactory = new GatewayFactory(); - // Register different gateways - gatewayFactory.registerGateway("ServiceA", new ExternalServiceA()); - gatewayFactory.registerGateway("ServiceB", new ExternalServiceB()); - gatewayFactory.registerGateway("ServiceC", new ExternalServiceC()); + // Register different gateways + gatewayFactory.registerGateway("ServiceA", new ExternalServiceA()); + gatewayFactory.registerGateway("ServiceB", new ExternalServiceB()); + gatewayFactory.registerGateway("ServiceC", new ExternalServiceC()); - // Use an executor service for asynchronous execution - Gateway serviceA = gatewayFactory.getGateway("ServiceA"); - Gateway serviceB = gatewayFactory.getGateway("ServiceB"); - Gateway serviceC = gatewayFactory.getGateway("ServiceC"); + // Use an executor service for execution + Gateway serviceA = gatewayFactory.getGateway("ServiceA"); + Gateway serviceB = gatewayFactory.getGateway("ServiceB"); + Gateway serviceC = gatewayFactory.getGateway("ServiceC"); - // Execute external services - try { - serviceA.execute(); - serviceB.execute(); - serviceC.execute(); - } catch (ThreadDeath e) { - LOGGER.info("Interrupted!" + e); - throw e; - } + // Execute external services + try { + serviceA.execute(); + serviceB.execute(); + serviceC.execute(); + } catch (ThreadDeath e) { + LOGGER.info("Interrupted!" + e); + throw e; } + } } ``` -The `Gateway` interface is extremely simple. +Running the example produces the following output. -```java -interface Gateway { - void execute() throws Exception; -} +``` +09:24:44.030 [main] INFO com.iluwatar.gateway.ExternalServiceA -- Executing Service A +09:24:45.038 [main] INFO com.iluwatar.gateway.ExternalServiceB -- Executing Service B +09:24:46.043 [main] INFO com.iluwatar.gateway.ExternalServiceC -- Executing Service C ``` -Program output: - -```java -Executing Service A -Executing Service B -Executing Service C -``` +This example demonstrates how the Gateway design pattern can be used to simplify the interaction with multiple external services. Each service is encapsulated behind a common interface, and the application interacts with this interface rather than directly with the services. This reduces coupling and makes the application easier to maintain and extend. ## Class diagram -![Gateway](./etc/gateway.urm.png "gateway") +![Gateway](./etc/gateway.urm.png "Gateway") ## Applicability Use the Gateway pattern when you need to integrate with remote services or APIs, and you want to minimize the coupling between your application and external systems. It is particularly useful in microservices architectures where different services need to communicate through well-defined APIs. -## Tutorials - -* [Pattern: API Gateway / Backends for Frontends](https://microservices.io/patterns/apigateway.html) - ## Known uses -* [10 most common use cases of an API Gateway](https://apisix.apache.org/blog/2022/10/27/ten-use-cases-api-gateway/) * API Gateways in Microservices: Acts as an intermediary that processes incoming requests from clients, directing them to appropriate services within a microservices architecture. * Database Gateways: Provides a unified interface to access data from various database systems, hiding the specifics of database querying and data retrieval. @@ -164,7 +157,6 @@ Trade-offs: ## Credits -* [Gateway - Martin Fowler](https://martinfowler.com/articles/gateway-pattern.html) -* [What is the difference between Facade and Gateway design patterns? - Stack Overflow](https://stackoverflow.com/questions/4422211/what-is-the-difference-between-facade-and-gateway-design-patterns) * [Enterprise Integration Patterns: Designing, Building, and Deploying Messaging Solutions](https://amzn.to/3WcFVui) * [Patterns of Enterprise Application Architecture](https://amzn.to/3WfKBPR) +* [Gateway (Martin Fowler)](https://martinfowler.com/articles/gateway-pattern.html)