🧭 Microservices Gateway with Ocelot and Swagger (.NET 9)

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.


πŸš€ Tech Stack

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)

πŸ—οΈ Architecture Overview

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚        API Gateway          β”‚
β”‚ (Ocelot + SwaggerForOcelot) β”‚
β”‚       Port: 5123            β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
        β”‚           β”‚
        β–Ό           β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚        AuthService          β”‚    β”‚         DataService          β”‚
β”‚  Issues JWT tokens          β”‚    β”‚  Returns product data        β”‚
β”‚  Port: 5138                 β”‚    β”‚  Port: 5146                 β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

πŸ“‚ Project Structure

MicroservicesOcelotDemo/
β”‚
β”œβ”€β”€ ApiGateway/
β”‚   β”œβ”€β”€ Program.cs
β”‚   β”œβ”€β”€ ocelot.json
β”‚
β”œβ”€β”€ AuthService/
β”‚   β”œβ”€β”€ Program.cs
β”‚
β”œβ”€β”€ DataService/
β”‚   β”œβ”€β”€ Program.cs
β”‚
└── TestClient/
    └── Program.cs

βš™οΈ Setup Instructions

1️⃣ Clone the Repository

git clone https://github.com/YOUR_USERNAME/MicroservicesOcelotDemo.git
cd MicroservicesOcelotDemo

2️⃣ Restore Dependencies

dotnet restore

3️⃣ Run Each Service in Separate Terminals

# 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

🌐 Access Points

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 Routing Summary

Gateway Path Forwards To Description
/auth/* http://localhost:5138/* Auth endpoints
/data/* http://localhost:5146/* Data endpoints
/swagger Aggregated docs SwaggerForOcelot UI

πŸ§ͺ Testing

βœ… Get a Token

curl -X POST http://localhost:5123/auth/token \
  -H "Content-Type: application/json" \
  -d '{ "username": "demo", "password": "demo" }'

βœ… Access Protected Data

curl http://localhost:5123/data/products \
  -H "Authorization: Bearer YOUR_JWT_TOKEN"

🧩 Key Configuration Files

ApiGateway/ocelot.json

{
  "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" }
}

πŸ’‘ Notes

  • 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.

πŸ“¦ NuGet Packages

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

πŸ“œ License

This project is licensed under the MIT License. Feel free to use, modify, and share.


πŸ‘€ Author

Spyros Ponaris πŸ’Ό LinkedIn