API Gateway


Microservices আর্কিটেকচারে, একাধিক সার্ভিস একে অপরের সঙ্গে কাজ করে। কিন্তু যখন ক্লায়েন্ট (যেমন মোবাইল অ্যাপ বা ওয়েব অ্যাপ) এই সার্ভিসগুলোকে একসাথে ব্যবহার করতে চায়, তখন সরাসরি প্রতিটি সার্ভিসে কল করা ঝামেলাপূর্ণ হয়। এই সমস্যার সমাধান হলো — API Gateway


API Gateway কী?

API Gateway হলো একটি single entry point যা ক্লায়েন্ট থেকে আসা সকল অনুরোধ গ্রহণ করে এবং সেগুলোকে সংশ্লিষ্ট microservice এ পাঠায়। এটি একধরনের রিভার্স প্রক্সি (Reverse Proxy) হিসেবে কাজ করে।


API Gateway কেন দরকার?

- এক জায়গা থেকে সব সার্ভিসে অ্যাক্সেস
- Authentication / Authorization একত্রে ম্যানেজ করা
- Request Routing ও Load Balancing
- Rate Limiting, Logging, Monitoring
- Circuit Breaker এবং Retry নিয়ন্ত্রণ


Spring Cloud Gateway কী?

Spring Boot এর জন্য সবচেয়ে জনপ্রিয় গেটওয়ে হলো Spring Cloud Gateway। এটি Reactive stack এর উপর তৈরি (Project Reactor) এবং Netty ব্যবহার করে — ফলে এটি দ্রুত, non-blocking এবং সহজে কনফিগারযোগ্য।


Step-by-Step Implementation


Dependency যোগ করো

pom.xml এ নিচের dependency দাও 👇

<dependencies>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-gateway</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
</dependencies>

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>2023.0.3</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>


Main Application

@SpringBootApplication
public class ApiGatewayApplication {
    public static void main(String[] args) {
        SpringApplication.run(ApiGatewayApplication.class, args);
    }
}


application.yml কনফিগারেশন

server:
  port: 8080

spring:
  cloud:
    gateway:
      routes:
        - id: user-service
          uri: http://localhost:8081/
          predicates:
            - Path=/user/**
        - id: order-service
          uri: http://localhost:8082/
          predicates:
            - Path=/order/**
      globalcors:
        corsConfigurations:
          '[/**]':
            allowedOrigins: "*"
            allowedMethods:
              - GET
              - POST
              - PUT
              - DELETE

এখানে /user/** রিকোয়েস্ট যাবে User Service এ এবং /order/** রিকোয়েস্ট যাবে Order Service এ।


Gateway Routing কীভাবে কাজ করে?

Spring Cloud Gateway প্রতিটি ইনকামিং রিকোয়েস্টকে নিচের ধাপে প্রক্রিয়া করে:

Predicate → কোন রিকোয়েস্ট কোন রুটে যাবে নির্ধারণ করে
Filter → রিকোয়েস্ট বা রেসপন্সের উপর পরিবর্তন আনে
Route → শেষ পর্যন্ত নির্দিষ্ট সার্ভিসে ফরওয়ার্ড করে


Custom Filter যোগ করা

তুমি চাইলে নিজস্ব লগিং বা authentication ফিল্টার তৈরি করতে পারো:

@Component
public class LoggingFilter implements GlobalFilter, Ordered {

    private static final Logger log = LoggerFactory.getLogger(LoggingFilter.class);

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        log.info("Incoming Request: {}", exchange.getRequest().getURI());
        return chain.filter(exchange)
                .then(Mono.fromRunnable(() ->
                        log.info("Outgoing Response: {}", exchange.getResponse().getStatusCode())));
    }

    @Override
    public int getOrder() {
        return -1;
    }
}

এই ফিল্টার প্রতিটি রিকোয়েস্টের URI এবং রেসপন্স স্ট্যাটাস লগ করবে।


Authentication সহ Gateway

Gateway তে JWT টোকেন ভ্যালিডেশনও যোগ করা যায়:

@Component
public class JwtAuthFilter implements GlobalFilter {

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        String token = exchange.getRequest().getHeaders().getFirst("Authorization");

        if (token == null || !token.startsWith("Bearer ")) {
            exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
            return exchange.getResponse().setComplete();
        }

        // token validation logic here
        return chain.filter(exchange);
    }
}


Load Balancing (Eureka সহ)

যদি তোমার সিস্টেমে Service Discovery (Eureka) থাকে, তাহলে সরাসরি URI এ সার্ভিস নাম ব্যবহার করা যায়:

spring:
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true

এবং uri: lb://user-service লিখলেই Gateway স্বয়ংক্রিয়ভাবে Eureka থেকে সার্ভিস লোকেশন খুঁজে নেবে।


API Gateway Lifecycle Diagram

Client → API Gateway → Filter (Auth, Logging)
                     ↓
                Route Matching
                     ↓
             Target Microservice
                     ↓
              Response → Gateway → Client


Spring Cloud Gateway এর সুবিধা

- Reactive & Non-blocking performance
- সহজ YAML ভিত্তিক রাউট কনফিগারেশন
- CORS, Rate Limiting, Security ফিল্টার সাপোর্ট
- Eureka বা Consul এর সাথে সহজ ইন্টিগ্রেশন
- Metrics, Logging ও Monitoring সুবিধা


Best Practices

- সমস্ত Authentication Gateway এ রাখো (downstream সার্ভিসে নয়)
- Fallback এবং Circuit Breaker যুক্ত করো Resilience4j বা Spring Cloud Circuit Breaker দিয়ে
- লগিং ও মেট্রিক মনিটর করো (Actuator + Prometheus)
- প্রোডাকশনে CORS ও RateLimiter সঠিকভাবে কনফিগার করো