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 MicroservicesOcelotDemo
dotnet 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.