This solution demonstrates a simple API Gateway built with Ocelot that routes traffic to two downstream microservices:
- AuthService β handles authentication and issues JWT tokens.
- DataService β exposes example data endpoints.
The gateway also aggregates both servicesβ Swagger documentation using SwaggerForOcelot, providing a unified API explorer at a single URL.
| Component | Purpose |
|---|---|
| .NET 9 | Framework for all services |
| Ocelot | API Gateway / Reverse Proxy |
| MMLib.SwaggerForOcelot | Aggregates Swagger from downstream services |
| Swashbuckle.AspNetCore | Swagger UI for microservices |
| JWT Bearer Auth | Token-based authentication (AuthService) |
βββββββββββββββββββββββββββββββ β API Gateway β β (Ocelot + SwaggerForOcelot) β β Port: 5123 β βββββββββ¬ββββββββββββ¬ββββββββββ β β βΌ βΌ βββββββββββββββββββββββββββββββ βββββββββββββββββββββββββββββββ β AuthService β β DataService β β Issues JWT tokens β β Returns product data β β Port: 5138 β β Port: 5146 β βββββββββββββββββββββββββββββββ βββββββββββββββββββββββββββββββ MicroservicesOcelotDemo/ β βββ ApiGateway/ β βββ Program.cs β βββ ocelot.json β βββ AuthService/ β βββ Program.cs β βββ DataService/ β βββ Program.cs β βββ TestClient/ βββ Program.cs git clone https://github.com/YOUR_USERNAME/MicroservicesOcelotDemo.git cd MicroservicesOcelotDemodotnet restore# Auth Service (port 5138) cd AuthService dotnet run --urls http://localhost:5138# Data Service (port 5146) cd DataService dotnet run --urls http://localhost:5146# API Gateway (port 5123) cd ApiGateway dotnet run --urls http://localhost:5123| URL | Description |
|---|---|
| http://localhost:5123/swagger | Aggregated Swagger (Auth + Data) |
| http://localhost:5123/auth/token | Token issuing endpoint (public) |
| http://localhost:5123/data/products | Data endpoint (example) |
| http://localhost:5138/swagger | AuthService Swagger |
| http://localhost:5146/swagger | DataService Swagger |
| Gateway Path | Forwards To | Description |
|---|---|---|
/auth/* | http://localhost:5138/* | Auth endpoints |
/data/* | http://localhost:5146/* | Data endpoints |
/swagger | Aggregated docs | SwaggerForOcelot UI |
curl -X POST http://localhost:5123/auth/token \ -H "Content-Type: application/json" \ -d '{ "username": "demo", "password": "demo" }'curl http://localhost:5123/data/products \ -H "Authorization: Bearer YOUR_JWT_TOKEN"{ "Routes": [ { "UpstreamPathTemplate": "/auth/{everything}", "UpstreamHttpMethod": [ "Get", "Post", "Put", "Delete", "Options" ], "DownstreamPathTemplate": "/{everything}", "DownstreamScheme": "http", "DownstreamHostAndPorts": [ { "Host": "localhost", "Port": 5138 } ] }, { "UpstreamPathTemplate": "/data/{everything}", "UpstreamHttpMethod": [ "Get", "Post", "Put", "Delete", "Options" ], "DownstreamPathTemplate": "/{everything}", "DownstreamScheme": "http", "DownstreamHostAndPorts": [ { "Host": "localhost", "Port": 5146 } ] } ], "SwaggerEndPoints": [ { "Key": "auth", "TransformByOcelotConfig": true, "Config": [ { "Name": "Auth Service", "Version": "v1", "Url": "http://localhost:5138/swagger/v1/swagger.json" } ] }, { "Key": "data", "TransformByOcelotConfig": true, "Config": [ { "Name": "Data Service", "Version": "v1", "Url": "http://localhost:5146/swagger/v1/swagger.json" } ] } ], "GlobalConfiguration": { "BaseUrl": "http://localhost:5123" } }- The gateway is configured purely as a reverse proxy β no authentication required.
- Both microservices have independent Swagger UIs.
- The gatewayβs Swagger aggregates both under
/swagger. - You can later enable JWT validation or rate limiting if needed.
| Project | Package | Purpose |
|---|---|---|
| ApiGateway | Ocelot | Reverse proxy / API Gateway |
| ApiGateway | MMLib.SwaggerForOcelot.AspNetCore | Aggregates Swagger docs |
| AuthService | Swashbuckle.AspNetCore | Swagger UI |
| DataService | Swashbuckle.AspNetCore | Swagger UI |
| AuthService / DataService | Microsoft.AspNetCore.Authentication.JwtBearer | JWT auth |
This project is licensed under the MIT License. Feel free to use, modify, and share.