API Gateway | Zuul | Microservices | Request Routing | සිංහලෙන් Full Guide

Zuul API Gateway: Smart Entry Point for Microservices SC Guide
ආයුබෝවන් යාළුවනේ!
අද අපි කතා කරන්න යන්නේ නූතන Software Development වලදී, විශේෂයෙන්ම Microservices Architecture එකක් පාවිච්චි කරනකොට, නැතුවම බැරි දෙයක් ගැන. ඒ තමයි API Gateway එකක්! අපි ගොඩක් වෙලාවට විශාල Applications හදනකොට, ඒක පොඩි පොඩි Services ගොඩකට කඩලා හදනවානේ. හැබැයි මේ හැම Service එකකටම Directly Access කරන එක Client කෙනෙක්ට හරිම අමාරු දෙයක්. ඒ වගේම Security, Monitoring, Load Balancing වගේ දේවලුත් අපි වෙන වෙනම Manage කරන්න ඕනේ. මේ හැම ප්රශ්නයකටම හොඳම විසඳුමක් තමයි API Gateway එකක් කියන්නේ.
මේ ලිපියෙන් අපි විශේෂයෙන්ම අවධානය යොමු කරන්නේ Netflixලා අපිට දීලා තියෙන සුපිරි Open Source Solution එකක් වෙන Zuul API Gateway එක ගැන. Zuul කියන්නේ අපේ Microservices වලට Smart Entry Point එකක් විදියට පාවිච්චි කරන්න පුළුවන්, ගොඩක් Powerful Tool එකක්. අපි මේකෙන් Requests Route කරන්නේ කොහොමද කියලා සරල උදාහරණයක් එක්ක බලමු. ඔයාගේ Project එකේ Microservices ගොඩක් තියෙනවා නම්, Client ලාට ඒ Services වලට Access කරන එක සරල කරන්න ඕනේ නම්, Security Layer එකක් දාගන්න ඕනේ නම්, මේ ලිපිය ඔයාට ගොඩක් වැදගත් වෙයි.
Zuul කියන්නේ මොකක්ද? (What is Zuul?)
සරලව කිව්වොත්, Zuul කියන්නේ Netflix විසින් හදපු API Gateway එකක්. මේක Java වලින් ලියලා තියෙන්නේ, ඒ වගේම Spring Boot Ecosystem එකත් එක්ක ගොඩක් හොඳට Integrate වෙනවා. Zuul වල ප්රධානම වැඩේ තමයි External Clients ලාගෙන් එන හැම Request එකක්ම අරගෙන, ඒ Request එක යවන්න ඕනේ හරි Microservice එකට Routing කරන එක. හරියට අපේ ගෙදරට එන අමුත්තෙක්ට අපි දොර පෙන්නලා, එයාට යන්න ඕනේ කාමරේට හරියටම පාර කියල දෙනවා වගේ වැඩක් තමයි මේකෙන් කරන්නේ.
සාමාන්යයෙන් API Gateway එකක්, Client ලා සහ Backend Microservices අතරේ තියෙන Reverse Proxy එකක් විදියට වැඩ කරනවා. Client ලා හැම වෙලාවෙම Request කරන්නේ API Gateway එකට. ඊට පස්සේ Gateway එක, ඒ Request එක, ඒකට අදාළ Internal Microservice එකට Forward කරනවා. මේ Forward කිරීමේදී Zuul වලට Security (Authentication/Authorization), Load Balancing, Monitoring, Request Throttling වගේ දේවල් කරන්නත් පුළුවන්. මේ හැමදේම එක තැනකින් Manage කරන්න පුළුවන් නිසා, අපේ Microservices වලට වෙන වෙනම මේ හැම Logic එකක්ම ලියන්න ඕනේ නැහැ. ඒක Development එක පහසු කරනවා වගේම Maintainability එකත් වැඩි කරනවා.
ඇයි අපිට Zuul වගේ API Gateway එකක් ඕනේ? (Why do we need an API Gateway like Zuul?)
හිතන්න ඔයාට Microservices 10ක් තියෙනවා කියලා. ඒ හැම එකක්ම වෙන වෙනම Port එකක, වෙන වෙනම Server වල Run වෙනවා. දැන් Client කෙනෙක්ට මේ Services වලට Access කරන්න ඕනේ නම්, එයාට මේ හැම Service එකකම URL එක දැනගන්න වෙනවා. උදාහරණයක් විදියට, Frontend Application එකකට User කෙනෙක්ගේ Profile Data ගන්න, Orders Process කරන්න, Products Display කරන්න වෙන වෙනම Endpoints 3කට Request කරන්න වෙනවා. මේක Frontend Development එකට ගොඩක් Complexity එකක් එකතු කරනවා. ඒ වගේම Backend Services වල Internal Structure එක Client ට Expose වෙන එක Security Risk එකක් වෙන්නත් පුළුවන්. මෙන්න මේ වගේ වෙලාවට තමයි API Gateway එකක් ගොඩක් ප්රයෝජනවත් වෙන්නේ.
API Gateway එකක් පාවිච්චි කරන එකෙන් අපිට ලැබෙන ප්රධාන වාසි ටිකක් බලමු:
- සරල Endpoint එකක් (Single Entry Point): Client ලාට තියෙන්නේ එකම URL එකකට Request යවන්න. Client ට Backend Microservices වල අභ්යන්තර ව්යුහය ගැන දැනගන්න අවශ්ය වෙන්නේ නැහැ. මේක Frontend Development එක සරල කරනවා වගේම, Microservices වෙනස් වුණත් Client ට ඒක දැනෙන්නේ නැහැ.
- Security Layer එකක් (Security): Authentication, Authorization, Rate Limiting වගේ Security Logic එක API Gateway එකෙන්ම කරලා, Internal Services වලට Direct Access එකක් නැතුව ආරක්ෂා කරන්න පුළුවන්. ඒ කියන්නේ අපිට Security Logic එක හැම Service එකකම Duplicate කරන්න ඕනේ නැහැ.
- Request Routing (Traffic Management): එන Request එකේ Path එක, Headers, හෝ වෙනත් Criteria එකක් අනුව, හරි Microservice එකට Request එක යවන්න පුළුවන්. මේක Dynamic Routing, A/B Testing වගේ දේවල් වලටත් පාවිච්චි කරන්න පුළුවන්.
- Load Balancing: Requests වැඩි වුණාම, Microservices Instances කිහිපයක් අතර Load එක බෙදා හරින්න API Gateway එකට පුළුවන්. Netflix Zuul, Netflix Ribbon හා Eureka Discovery Service එක්ක Integrate වෙලා මේ Feature එක ලබා දෙනවා.
- Monitoring and Logging: හැම Request එකක්ම API Gateway එක හරහා යන නිසා, Traffic එක Monitor කරන්න, Performance Metrics ගන්න, Logs ගන්න පහසුයි. මේකෙන් අපිට System Behavior එක ගැන හොඳ අවබෝධයක් ගන්න පුළුවන්.
- Caching: නිතර නිතර Request කරන Data API Gateway Layer එකේම Cache කරලා, Backend Services වලට යන Load එක අඩු කරලා, Performance එක වැඩි කරන්න පුළුවන්.
මේ වාසි නිසා තමයි අද ගොඩක් Modern Applications වල API Gateway එකක් අත්යවශ්යම අංගයක් වෙලා තියෙන්නේ.
Zuul Routing වැඩ කරන්නේ කොහොමද? (How does Zuul Routing work?)
Zuul වල Routing වැඩ කරන්නේ ගොඩක් සරලව. අපි Application Configuration එකේ (application.yml
හෝ application.properties
) Rules ටිකක් ලියනවා. මේ Rules වලින් කියන්නේ, මේ වගේ Path එකකට Request එකක් ආවොත්, මේ Service එකට යවන්න කියලා. Zuul ට මේ Routes පටලවා නොගෙන හඳුනා ගන්න පුළුවන් වෙන්නේ අපිට Custom Patterns හදන්න පුළුවන් නිසා.
උදාහරණයක් විදියට, අපිට User Service එකක් හා Product Service එකක් තියෙනවා කියලා හිතමු. User Service එක Port 8081 වල Run වෙනවා, Product Service එක Port 8082 වල Run වෙනවා. දැන් අපේ Zuul Gateway එක Port 8080 වල Run වෙනවා නම්, අපිට මේ වගේ Config එකක් ලියන්න පුළුවන්:
zuul:
routes:
users-service: # Route ID එකක්, කැමති නමක් දෙන්න පුළුවන්
path: /api/users/** # Zuul Gateway එකට එන Request Path Pattern එක
url: http://localhost:8081/ # මේ Request එක Route කරන්න ඕනේ Internal Service URL එක
products-service:
path: /api/products/**
url: http://localhost:8082/
මේ Config එකෙන් කියන්නේ:
users-service
කියන Route ID එකට අදාළව,/api/users/**
වගේ Path එකක් එක්ක Zuul Gateway එකට එන ඕනෑම Request එකක්http://localhost:8081/
කියන URL එකට Route කරන්න කියලා. මෙතැනදී wildcard (**) එකෙන් කියන්නේ/api/users/
කියන Path එකෙන් පස්සේ මොනවා තිබුණත් ඒ Request එක මේ Service එකට යවනවා කියන එකයි. Zuul Default විදියට Prefix එක (මේ Example එකේදී/api/users
) Stripping කරන නිසා, Service එකට යවන්නේhttp://localhost:8081/
එකට පස්සේ තියෙන ඉතුරු Path එක. උදාහරණයක් විදියට/api/users/123
Request එකhttp://localhost:8081/123
විදියට Forward කරනවා.- ඒ වගේම
products-service
කියන Route ID එකට අදාළව,/api/products/**
වගේ Path එකක් එක්ක එන ඕනෑම Request එකක්http://localhost:8082/
කියන URL එකට Route කරන්න.
ඉතින් දැන් Client කෙනෙක් http://localhost:8080/api/users/123
කියලා Request එකක් යැව්වොත්, Zuul ඒක අරගෙන, http://localhost:8081/users/123
(Service එකේ Controller Mapping එකට අනුව) කියන URL එකට Internal එකෙන්ම Forward කරනවා. Client ට මේ Internal URL එක ගැන කිසිම දෙයක් දැනගන්න අවශ්ය වෙන්නේ නැහැ. මේක ගොඩක් සරලයි වගේම ගොඩක් Powerful Feature එකක්!
Zuul වලට Eureka Discovery Service එකක් එක්කත් Integrate වෙන්න පුළුවන්. ඒකෙන් වෙන්නේ, අපේ Microservices වල URL වෙනස් වුණත් (උදා: Dynamic IP Addresses), Zuul ට ඒක Automatically Detect කරලා Routing කරන්න පුළුවන් වීම. ඒ කියන්නේ අපිට Hardcode URL දාන්න ඕනේ නැහැ. ඒක ගැන අපි පස්සේ තව ලිපියකින් කතා කරමු.
ප්රායෝගික උදාහරණයක්: Zuul සමග Request Route කරමු (Practical Example: Let's Route Requests with Zuul)
දැන් අපි බලමු මේක Practical විදියට කරන්නේ කොහොමද කියලා. අපි සරල Spring Boot Microservices දෙකක් හා Zuul API Gateway එකක් හදමු.
1. Project Setup
අපි Spring Initializr එකට ගිහින් Maven Project තුනක් හදමු. හැම Project එකටම Java 11+ සහ Spring Boot 2.x (හෝ 3.x, නමුත් Zuul Spring Boot 3 වලට Native Support කරන්නේ නැහැ, Spring Cloud Gateway තමයි Recommended) පාවිච්චි කරන්න. මේ Example එක Spring Boot 2.x එක්ක Compatible.
user-service
: Dependencies:Spring Web
product-service
: Dependencies:Spring Web
api-gateway
: Dependencies:Spring Web
,Netflix Zuul Gateway
2. user-service හදමු
මුලින්ම user-service
එක හදමු. මේකෙන් User Details ලබා දෙන සරල API එකක් තියෙනවා.
pom.xml
එකේ Dependency එක:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
application.yml
එකේ Port එක Configure කරමු. මේකෙන් අපේ User Service එක Run වෙන Port එක සඳහන් කරනවා:
server:
port: 8081 # User Service එක සඳහා Port 8081
spring:
application:
name: user-service # Service එකේ නම
සරල Controller එකක් ලියමු. මේක /users
Path එකට එන Requests Handle කරනවා:
package com.example.userservice.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/users") // මේ Service එකේ Base Path එක
public class UserController {
@GetMapping("/{id}")
public String getUserById(@PathVariable String id) {
return "User details for ID: " + id + " from User Service (Port 8081)";
}
@GetMapping("/hello")
public String helloUser() {
return "Hello from User Service!";
}
}
3. product-service හදමු
ඊළඟට product-service
එක හදමු. මේකෙන් Product Details ලබා දෙන සරල API එකක් තියෙනවා.
product-service
එකේ pom.xml
එක user-service
එකට සමානයි, Spring Web Dependency එක විතරයි තියෙන්නේ.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
application.yml
එකේ Port එක Configure කරමු:
server:
port: 8082 # Product Service එක සඳහා Port 8082
spring:
application:
name: product-service
සරල Controller එකක් ලියමු:
package com.example.productservice.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/products") // මේ Service එකේ Base Path එක
public class ProductController {
@GetMapping("/{id}")
public String getProductById(@PathVariable String id) {
return "Product details for ID: " + id + " from Product Service (Port 8082)";
}
@GetMapping("/hello")
public String helloProduct() {
return "Hello from Product Service!";
}
}
4. api-gateway (Zuul) හදමු
දැන් අපේ ප්රධාන Component එක වන Zuul API Gateway එක හදමු. මේකෙන් තමයි එන Requests හරි Service එකට Route කරන්නේ.
api-gateway
එකේ pom.xml
එකට Zuul Dependency එක එකතු කරමු. ඒ වගේම, Spring Cloud Dependencies වලට හරියට Version එකක් Match කරන්න, spring-cloud-dependencies
Bill of Materials (BOM) එක dependencyManagement
සෙක්ෂන් එකට එකතු කරන්න අමතක කරන්න එපා. මේකෙන් වෙන්නේ Spring Cloud Dependencies වලට හරියට Compatible Version එකක් Apply කරන එකයි.
<!-- Zuul Gateway Dependency -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
</dependency>
<!-- Web Dependency (required for Spring Boot application) -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Spring Cloud BOM for dependency management -->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>2.2.10.RELEASE</version> <!-- ඔබේ Spring Boot Version එකට ගැලපෙන Version එකක් දාන්න. https://spring.io/projects/spring-cloud වෙතින් බලාගන්න -->
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
application.yml
එකේ Zuul Configuration එක එකතු කරමු:
server:
port: 8080 # API Gateway එක Run වෙන Port එක
spring:
application:
name: api-gateway
zuul:
routes:
user-service: # Route ID: User Service එකට අදාළ Route එක
path: /api/users/** # Gateway එකට එන Path Pattern එක
url: http://localhost:8081 # Request එක Forward කරන Internal Service URL එක
product-service: # Route ID: Product Service එකට අදාළ Route එක
path: /api/products/**
url: http://localhost:8082
main
Application Class එකේ Zuul Gateway එක Enable කරන්න @EnableZuulProxy
Annotation එක එකතු කරන්න ඕනේ:
package com.example.apigateway;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy; // මේ Annotation එක අත්යවශ්යයි
@EnableZuulProxy // Zuul Proxy එක Enable කරන්න
@SpringBootApplication
public class ApiGatewayApplication {
public static void main(String[] args) {
SpringApplication.run(ApiGatewayApplication.class, args);
}
}
5. Testing
දැන් අපි හැම Service එකක්ම Run කරමු. මුලින්ම user-service
(Port 8081) සහ product-service
(Port 8082) Run කරන්න. ඊට පස්සේ api-gateway
(Port 8080) Run කරන්න. මේ Services IntelliJ IDEA, Eclipse වගේ IDE එකකින් හෝ Command Line එකෙන් mvn spring-boot:run
විධානය පාවිච්චි කරලා Run කරන්න පුළුවන්.
දැන් Postman, Insomnia, හෝ Curl වගේ Tool එකක් පාවිච්චි කරලා Test කරමු.
User Service එකට Request යවමු:
curl http://localhost:8080/api/users/123
Output: User details for ID: 123 from User Service (Port 8081)
curl http://localhost:8080/api/users/hello
Output: Hello from User Service!
Product Service එකට Request යවමු:
curl http://localhost:8080/api/products/ABC
Output: Product details for ID: ABC from Product Service (Port 8082)
curl http://localhost:8080/api/products/hello
Output: Hello from Product Service!
දැන් ඔයාලට පේනවා ඇති, අපි හැම Request එකක්ම යැව්වේ API Gateway එකට (Port 8080). ඒත් Zuul ඒ Request එක හරි Microservice එකට Route කළා. Client ට Internal Service URLs ගැන කිසිම දෙයක් දැනගන්න අවශ්ය වුණේ නැහැ. සුපිරි වැඩක් නේද?
Zuul වලට තව මොනවද කරන්න පුළුවන්? (What else can Zuul do?)
Zuul කියන්නේ නිකන්ම Routing කරන Tool එකක් නෙවෙයි. මේකට Filters කියන Concept එක හරහා ගොඩක් දේවල් කරන්න පුළුවන්. Zuul Filters වලින් වෙන්නේ, Request එක Microservice එකට යන ගමනේදී හෝ Response එක Client ට ආපහු එන ගමනේදී, අපිට ඕනේ Logic එකක් Execute කරන්න පුළුවන් වීම.
Zuul Filters ප්රධාන වශයෙන් වර්ග හතරකට බෙදෙනවා:
- Pre Filters: Request එක Origin Server එකට යන්න කලින් Execute වෙනවා. මේවා Authentication (JWT Validation), Logging (Correlation IDs එකතු කිරීම), Rate Limiting වගේ දේවල් වලට පාවිච්චි කරන්න පුළුවන්. උදාහරණයක් විදියට, Request එකට අදාළ Authentication Token එකක් Validate කරලා, Valid නම් විතරක් Request එක Forward කරන්න මේ Filters පාවිච්චි කරන්න පුළුවන්.
- Route Filters: Request එක Origin Server එකට Route කරන වෙලාවේදී Execute වෙනවා. Dynamic Routing, Load Balancing Decisions වගේ දේවල් වලට මේවා ප්රයෝජනවත්. Zuul වල Default Routing Logic එක වැඩ කරන්නේ මේ Phase එකේදී.
- Post Filters: Response එක Origin Server එකෙන් ආවට පස්සේ, Client ට යවන්න කලින් Execute වෙනවා. Data Transformation, Adding Headers (e.g., Security Headers), Compressing Response Bodies, Collecting Metrics about Response Times වගේ දේවල් වලට මේවා පාවිච්චි කරන්න පුළුවන්.
- Error Filters: Request Processing එකේදී Error එකක් ආවොත් Execute වෙනවා. Custom Error Responses හදන්න, Error Logs කරන්න මේවා ප්රයෝජනවත්. මේකෙන් අපිට Client ට වඩාත් User-friendly Error Messages දෙන්න පුළුවන්.
මේ Filters ගැනත් අපි වෙනම ලිපියකින් කතා කරමු. මේවා පාවිච්චි කරලා අපිට ගොඩක් Advanced Features අපේ API Gateway එකට එකතු කරන්න පුළුවන්. මේවා තමයි Zuul කියන Solution එකේ Flexibility එක වැඩි කරන ප්රධානම සාධකය.
අවසන් අදහස (Final Thoughts)
ඉතින් අද අපි කතා කළේ Zuul API Gateway එකක් මොකක්ද, ඒකෙන් මොනවද කරන්න පුළුවන්, සහ කොහොමද සරලව Request Route කරන්නේ කියලා. ඔයාලට දැන් තේරෙනවා ඇති Microservices Architectures වල API Gateway එකක් කියන්නේ කොච්චර වැදගත් දෙයක්ද කියලා. Zuul වගේ Gateway එකක් පාවිච්චි කරන එකෙන් අපිට Scalability, Security, Maintainability, සහ Developer Experience වගේ ගොඩක් දේවල් වැඩි දියුණු කරගන්න පුළුවන්. එය අපේ Backend Infrastructure එකට එන Traffic එක හොඳින් Manage කරගන්න උපකාරී වෙනවා.
මතක තියාගන්න, මේක Zuul වල මූලිකම Feature එකක් විතරයි. Zuul වලට තව ගොඩක් දේවල් කරන්න පුළුවන්. මේ ලිපිය ඔයාලට Zuul ගැන මූලික අවබෝධයක් දෙන්න ඇති කියලා හිතනවා. ඒ වගේම මේක Spring Cloud Gateway වගේ අලුත් Gateway Solutions වලටත් හොඳ පදනමක්. (Spring Boot 3+ නම් Spring Cloud Gateway තමයි Recommended වෙන්නේ.)
දැන් ඔයාලට පුළුවන් මේ Concepts පාවිච්චි කරලා පොඩි Project එකක් හදලා බලන්න. මොනවා හරි ප්රශ්න තියෙනවා නම් හෝ ඔයාලගේ අදහස් තියෙනවා නම් පහලින් Comment එකක් දාගෙන යන්න. ඒ වගේම මේ ලිපිය ඔයාලගේ යාළුවන්ටත් Share කරන්න අමතක කරන්න එපා. අපි තව අලුත් Tech Topics එකක් එක්ක ඉක්මනින්ම හම්බවෙමු!
සුභ දවසක්!