SwitchboardApplicationProxy 3.0.14

dotnet add package SwitchboardApplicationProxy --version 3.0.14
                    
NuGet\Install-Package SwitchboardApplicationProxy -Version 3.0.14
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="SwitchboardApplicationProxy" Version="3.0.14" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="SwitchboardApplicationProxy" Version="3.0.14" />
                    
Directory.Packages.props
<PackageReference Include="SwitchboardApplicationProxy" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add SwitchboardApplicationProxy --version 3.0.14
                    
#r "nuget: SwitchboardApplicationProxy, 3.0.14"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package SwitchboardApplicationProxy@3.0.14
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=SwitchboardApplicationProxy&version=3.0.14
                    
Install as a Cake Addin
#tool nuget:?package=SwitchboardApplicationProxy&version=3.0.14
                    
Install as a Cake Tool

<div align="center"> <img src="https://github.com/jchristn/switchboard/blob/main/assets/icon.png?raw=true" width="140" height="128" alt="Switchboard">

Switchboard

A lightweight reverse proxy and API gateway for .NET

NuGet Version NuGet Downloads Docker Hub License: MIT </div>


Overview

Switchboard is a production-ready reverse proxy and API gateway that combines enterprise-grade features with .NET simplicity. Route traffic to multiple backends, automatically handle failures, enforce rate limits, and implement custom authenticationβ€”all with minimal configuration.

πŸš€ Flexible Deployment: Embed directly into your .NET application as a library or run as a standalone server.


Table of Contents


What is Switchboard?

Switchboard is a lightweight application proxy that combines reverse proxy and API gateway functionality for .NET applications. It acts as an intelligent intermediary between your clients and backend services, providing:

  • Traffic routing to multiple origin servers
  • Automatic health checking and failover
  • Load balancing across healthy backends
  • Rate limiting to protect your services
  • Authentication and authorization via flexible callbacks
  • URL rewriting for API versioning
  • Protocol support for HTTP, chunked transfer encoding, and server-sent events (SSE)

Built on .NET 8.0, Switchboard is designed for developers who need a simple, embeddable gateway without the complexity of heavyweight solutions.


Key Features

βœ… Flexible Load Balancing – Round-robin or random distribution across healthy origin servers βœ… Automatic Health Checks – Continuous monitoring with configurable thresholds βœ… Rate Limiting – Per-origin concurrent request limits and throttling βœ… Custom Authentication – Callback-based auth/authz with context forwarding βœ… URL Rewriting – Transform URLs before proxying to backends βœ… Protocol Support – HTTP/1.1, chunked transfer encoding, server-sent events βœ… Smart Routing – Parameterized URLs with wildcard matching (/users/{id}) βœ… Header Management – Automatic proxy headers and configurable blocking βœ… Logging – Built-in syslog integration with multiple severity levels βœ… Docker Ready – Available on Docker Hub βœ… Embeddable – Integrate directly into your application via NuGet βœ… OpenAPI Support – Auto-generate OpenAPI 3.0.3 docs with Swagger UI


Who is it for?

Switchboard is designed for:

  • Backend Developers building microservices architectures
  • DevOps Engineers needing lightweight reverse proxy solutions
  • API Platform Teams implementing centralized gateways
  • .NET Developers who want embeddable proxy functionality
  • System Architects designing high-availability systems
  • Startups seeking simple, cost-effective infrastructure

When to Use Switchboard

Perfect for:

  • Routing requests to multiple backend microservices
  • Load balancing across identical service instances
  • Centralizing authentication and authorization
  • Implementing API versioning with URL rewrites
  • Protecting backends from overload with rate limiting
  • Building high-availability systems with automatic failover
  • Proxying server-sent events or chunked responses
  • Embedding a gateway directly into your .NET application

Not ideal for:

  • Simple single-backend scenarios (use a direct connection)
  • WebSocket proxying (use dedicated WebSocket gateways)
  • Advanced routing rules (use full-featured API gateways like Kong, Tyk, or NGINX)
  • Layer 4 load balancing (use HAProxy or cloud load balancers)

What It Does

Switchboard provides:

  1. Request Routing – Match incoming requests to API endpoints using parameterized URLs
  2. Load Balancing – Distribute traffic across multiple origin servers (round-robin or random)
  3. Health Monitoring – Automatically detect and route around unhealthy backends
  4. Rate Limiting – Enforce concurrent request limits per origin server
  5. Authentication – Invoke custom callbacks for auth/authz decisions
  6. Authorization Context – Forward auth metadata to origin servers via headers
  7. URL Transformation – Rewrite URLs before forwarding to backends
  8. Error Handling – Return structured JSON error responses
  9. Protocol Handling – Support chunked transfer encoding and server-sent events
  10. Logging – Comprehensive request/response logging with syslog integration

What It Doesn't Do

Switchboard is intentionally lightweight and does not include:

  • ❌ WebSocket proxying
  • ❌ Advanced traffic shaping or QoS
  • ❌ Built-in caching (use Redis or CDN)
  • ❌ Request transformation/mutation (header rewriting beyond proxy headers)
  • ❌ OAuth/JWT validation (implement via callbacks)
  • ❌ GraphQL federation
  • ❌ Service mesh features (circuit breakers, retries, distributed tracing)
  • ❌ GUI/dashboard (use monitoring tools like Grafana)

For these features, consider integrating Switchboard with specialized tools or using enterprise API gateways.


Quick Start

1. Install via NuGet (Integrated)

dotnet add package SwitchboardApplicationProxy

2. Run as Standalone Server

# Clone the repository
git clone https://github.com/jchristn/switchboard.git
cd Switchboard-3.0/src

# Build the solution
dotnet build

# Run the server
cd Switchboard.Server/bin/Debug/net8.0
dotnet Switchboard.Server.dll

3. Run with Docker

docker pull jchristn/switchboard
docker run -p 8000:8000 -v $(pwd)/sb.json:/app/sb.json jchristn/switchboard

Visit http://localhost:8000/ to confirm Switchboard is running!


Installation

NuGet Package

Install the SwitchboardApplicationProxy package from NuGet:

dotnet add package SwitchboardApplicationProxy

Or via Package Manager Console:

Install-Package SwitchboardApplicationProxy

Docker Image

Pull from Docker Hub:

docker pull jchristn/switchboard

Docker image: jchristn/switchboard

Build from Source

git clone https://github.com/jchristn/switchboard.git
cd Switchboard-3.0/src
dotnet build

Usage Examples

Integrated (Library)

Embed Switchboard directly into your .NET application:

using Switchboard.Core;

// Initialize settings
SwitchboardSettings settings = new SwitchboardSettings();

// Add API endpoint with parameterized URLs
settings.Endpoints.Add(new ApiEndpoint
{
    Identifier = "user-api",
    Name = "User Management API",
    LoadBalancing = LoadBalancingMode.RoundRobin,

    // Public routes (no authentication)
    Unauthenticated = new ApiEndpointGroup
    {
        ParameterizedUrls = new Dictionary<string, List<string>>
        {
            { "GET", new List<string> { "/health", "/status" } }
        }
    },

    // Protected routes (require authentication)
    Authenticated = new ApiEndpointGroup
    {
        ParameterizedUrls = new Dictionary<string, List<string>>
        {
            { "GET", new List<string> { "/users", "/users/{userId}" } },
            { "POST", new List<string> { "/users" } },
            { "PUT", new List<string> { "/users/{userId}" } },
            { "DELETE", new List<string> { "/users/{userId}" } }
        }
    },

    // URL rewriting (e.g., API versioning)
    RewriteUrls = new Dictionary<string, Dictionary<string, string>>
    {
        {
            "GET", new Dictionary<string, string>
            {
                { "/users/{userId}", "/api/v2/users/{userId}" }
            }
        }
    },

    // Associate with origin servers
    OriginServers = new List<string> { "backend-1", "backend-2" }
});

// Add origin servers
settings.Origins.Add(new OriginServer
{
    Identifier = "backend-1",
    Name = "Backend Server 1",
    Hostname = "api1.example.com",
    Port = 443,
    Ssl = true,
    HealthCheckUrl = "/health",
    MaxParallelRequests = 20,
    RateLimitRequestsThreshold = 50
});

settings.Origins.Add(new OriginServer
{
    Identifier = "backend-2",
    Name = "Backend Server 2",
    Hostname = "api2.example.com",
    Port = 443,
    Ssl = true,
    HealthCheckUrl = "/health",
    MaxParallelRequests = 20,
    RateLimitRequestsThreshold = 50
});

// Start Switchboard
using (SwitchboardDaemon sb = new SwitchboardDaemon(settings))
{
    // Define authentication callback
    sb.Callbacks.AuthenticateAndAuthorize = async (ctx) =>
    {
        // Custom authentication logic (e.g., JWT validation)
        string authHeader = ctx.Request.Headers.Get("Authorization");

        if (string.IsNullOrEmpty(authHeader))
        {
            return new AuthContext
            {
                Authentication = new AuthenticationContext { Result = AuthenticationResultEnum.Unauthenticated },
                Authorization = new AuthorizationContext { Result = AuthorizationResultEnum.Unauthorized }
            };
        }

        // Validate token (example)
        bool isValid = ValidateToken(authHeader);

        return new AuthContext
        {
            Authentication = new AuthenticationContext
            {
                Result = isValid ? AuthenticationResultEnum.Success : AuthenticationResultEnum.Unauthenticated,
                Metadata = new Dictionary<string, string> { { "UserId", "12345" } }
            },
            Authorization = new AuthorizationContext
            {
                Result = isValid ? AuthorizationResultEnum.Success : AuthorizationResultEnum.Unauthorized,
                Metadata = new Dictionary<string, string> { { "Role", "Admin" } }
            }
        };
    };

    Console.WriteLine("Switchboard is running on http://localhost:8000");
    Console.ReadLine();
}

Standalone Server

Run Switchboard as an independent server using a configuration file:

1. Create sb.json configuration:
{
  "Logging": {
    "SyslogServerIp": null,
    "SyslogServerPort": 514,
    "MinimumSeverity": "Info",
    "LogRequests": true,
    "LogResponses": false,
    "ConsoleLogging": true
  },
  "Endpoints": [
    {
      "Identifier": "my-api",
      "Name": "My API",
      "LoadBalancing": "RoundRobin",
      "Unauthenticated": {
        "ParameterizedUrls": {
          "GET": ["/health", "/status"]
        }
      },
      "Authenticated": {
        "ParameterizedUrls": {
          "GET": ["/users", "/users/{id}"],
          "POST": ["/users"],
          "PUT": ["/users/{id}"],
          "DELETE": ["/users/{id}"]
        }
      },
      "OriginServers": ["backend-1", "backend-2"]
    }
  ],
  "Origins": [
    {
      "Identifier": "backend-1",
      "Name": "Backend 1",
      "Hostname": "localhost",
      "Port": 8001,
      "Ssl": false,
      "HealthCheckIntervalMs": 5000,
      "HealthyThreshold": 2,
      "UnhealthyThreshold": 2,
      "MaxParallelRequests": 10,
      "RateLimitRequestsThreshold": 30
    },
    {
      "Identifier": "backend-2",
      "Name": "Backend 2",
      "Hostname": "localhost",
      "Port": 8002,
      "Ssl": false,
      "HealthCheckIntervalMs": 5000,
      "HealthyThreshold": 2,
      "UnhealthyThreshold": 2,
      "MaxParallelRequests": 10,
      "RateLimitRequestsThreshold": 30
    }
  ],
  "Webserver": {
    "Hostname": "localhost",
    "Port": 8000
  }
}
2. Start the server:
dotnet Switchboard.Server.dll

            _ _      _    _                      _
  ____ __ _(_) |_ __| |_ | |__  ___  __ _ _ _ __| |
 (_-< V  V / |  _/ _| ' \| '_ \/ _ \/ _` | '_/ _` |
 /__/\_/\_/|_|\__\__|_||_|_.__/\___/\__,_|_| \__,_|

Switchboard Server v3.0.x

Loading from settings file ./sb.json
[INFO] Webserver started on http://localhost:8000
[INFO] Switchboard Server started
3. Test the endpoint:
curl http://localhost:8000/health

Docker

Using Docker Compose:
# docker-compose.yml
version: '3.8'
services:
  switchboard:
    image: jchristn/switchboard:latest
    ports:
      - "8000:8000"
    volumes:
      - ./sb.json:/app/sb.json
    restart: unless-stopped

Start with Docker Compose:

# Use provided scripts
cd Docker
./compose-up.sh  # Linux/Mac
compose-up.bat   # Windows

# Or manually
docker-compose up -d

Stop with Docker Compose:

./compose-down.sh  # Linux/Mac
compose-down.bat   # Windows
Manual Docker Run:
docker run -d \
  --name switchboard \
  -p 8000:8000 \
  -v $(pwd)/sb.json:/app/sb.json \
  jchristn/switchboard:latest

Configuration

Default Behavior

By default, Switchboard:

  • Listens on http://localhost:8000/
  • Returns a default homepage at / (GET/HEAD requests)
  • Requires explicit API endpoint and origin server configuration

Health Check Defaults

If not explicitly configured:

  • Method: GET /
  • Interval: Every 5 seconds (HealthCheckIntervalMs)
  • Unhealthy Threshold: 2 consecutive failures (UnhealthyThreshold)
  • Healthy Threshold: 2 consecutive successes (HealthyThreshold)

Rate Limiting Defaults

If not explicitly configured:

  • Max Parallel Requests: 10 per origin (MaxParallelRequests)
  • Rate Limit Threshold: 30 total requests (active + pending) per origin (RateLimitRequestsThreshold)

Configuration File Options

For standalone deployment, customize sb.json with:

  • Logging – Syslog servers, severity levels, console output
  • Endpoints – API routes, authentication groups, URL rewrites
  • Origins – Backend servers, health checks, rate limits
  • BlockedHeaders – Headers to filter from requests/responses
  • Webserver – Hostname, port, SSL settings

Refer to the Test project for a comprehensive configuration example.


Advanced Features

URL Rewriting

Transform URLs before proxying to backends:

RewriteUrls = new Dictionary<string, Dictionary<string, string>>
{
    {
        "GET", new Dictionary<string, string>
        {
            { "/v2/users/{userId}", "/v1/users/{userId}" }, // API versioning
            { "/api/data", "/legacy/data" }                 // Path migration
        }
    }
}

Authentication Context Forwarding

Pass authentication metadata to origin servers:

sb.Callbacks.AuthenticateAndAuthorize = async (ctx) =>
{
    return new AuthContext
    {
        Authentication = new AuthenticationContext
        {
            Result = AuthenticationResultEnum.Success,
            Metadata = new Dictionary<string, string>
            {
                { "UserId", "12345" },
                { "Email", "user@example.com" }
            }
        },
        Authorization = new AuthorizationContext
        {
            Result = AuthorizationResultEnum.Success,
            Metadata = new Dictionary<string, string>
            {
                { "Role", "Admin" },
                { "Permissions", "read,write,delete" }
            }
        }
    };
};

The auth context is automatically serialized and forwarded via the x-sb-auth-context header (base64-encoded).

Server-Sent Events (SSE)

Switchboard transparently proxies server-sent events:

// No special configuration needed
// SSE streams are automatically detected via Content-Type: text/event-stream

Chunked Transfer Encoding

Automatically handled for both requests and responses.

OpenAPI Documentation

Switchboard can automatically generate OpenAPI 3.0.3 documentation for your proxied routes and serve a Swagger UI:

Enable OpenAPI (JSON Configuration)
{
  "OpenApi": {
    "Enable": true,
    "EnableSwaggerUi": true,
    "DocumentPath": "/openapi.json",
    "SwaggerUiPath": "/swagger",
    "Title": "My API Gateway",
    "Version": "1.0.0",
    "Description": "API Gateway for microservices",
    "Contact": {
      "Name": "API Support",
      "Email": "support@example.com",
      "Url": "https://example.com/support"
    },
    "License": {
      "Name": "MIT",
      "Url": "https://opensource.org/licenses/MIT"
    },
    "Servers": [
      { "Url": "https://api.example.com", "Description": "Production" },
      { "Url": "https://staging-api.example.com", "Description": "Staging" }
    ],
    "SecuritySchemes": {
      "bearerAuth": {
        "Type": "http",
        "Scheme": "bearer",
        "BearerFormat": "JWT",
        "Description": "JWT Bearer token authentication"
      }
    },
    "Tags": [
      { "Name": "Users", "Description": "User management operations" },
      { "Name": "Products", "Description": "Product catalog operations" }
    ]
  },
  "Endpoints": [...]
}
Add Custom Route Documentation

Document individual routes with detailed metadata on each endpoint:

{
  "Endpoints": [
    {
      "Identifier": "user-api",
      "Name": "User API",
      "Unauthenticated": {
        "ParameterizedUrls": {
          "GET": ["/api/users/{id}"]
        }
      },
      "Authenticated": {
        "ParameterizedUrls": {
          "POST": ["/api/users"],
          "PUT": ["/api/users/{id}"]
        }
      },
      "OpenApiDocumentation": {
        "Routes": {
          "GET": {
            "/api/users/{id}": {
              "OperationId": "getUserById",
              "Summary": "Get a user by ID",
              "Description": "Retrieves detailed information about a specific user.",
              "Tags": ["Users"],
              "Parameters": [
                {
                  "Name": "id",
                  "In": "path",
                  "Required": true,
                  "SchemaType": "integer",
                  "Description": "The unique user identifier"
                }
              ],
              "Responses": {
                "200": { "Description": "User found successfully" },
                "404": { "Description": "User not found" }
              }
            }
          },
          "POST": {
            "/api/users": {
              "OperationId": "createUser",
              "Summary": "Create a new user",
              "Tags": ["Users"],
              "RequestBody": {
                "Description": "User data to create",
                "Required": true,
                "Content": {
                  "application/json": {
                    "SchemaType": "object"
                  }
                }
              },
              "Responses": {
                "201": { "Description": "User created successfully" },
                "400": { "Description": "Invalid request data" }
              }
            }
          }
        }
      },
      "OriginServers": ["backend-1"]
    }
  ]
}
Auto-Generated Documentation

Routes without explicit OpenApiDocumentation are automatically documented with:

  • Summary: Generated from HTTP method and path (e.g., "GET /api/users/{id}")
  • Tags: Uses the endpoint's Name or Identifier
  • Path Parameters: Automatically extracted from URL patterns like {id}
  • Security: Automatically added for routes in Authenticated groups
Accessing Documentation

Once enabled, access your API documentation at:

  • OpenAPI JSON: http://localhost:8000/openapi.json
  • Swagger UI: http://localhost:8000/swagger

Support

Getting Help

  • Documentation: Check the README and code examples in the Test project
  • GitHub Issues: Report bugs or request features at GitHub Issues
  • GitHub Discussions: Ask questions and share ideas at GitHub Discussions

We welcome your feedback and contributions!


Contributing

We'd love your help improving Switchboard! Contributions are welcome in many forms:

  • Code: New features, bug fixes, performance optimizations
  • Documentation: Improve guides, add examples, fix typos
  • Testing: Write tests, report bugs, validate fixes
  • Ideas: Suggest features, share use cases, provide feedback

How to Contribute:

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add amazing feature')
  4. Push to your branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

Please ensure your code follows existing conventions and includes tests where applicable.


License

Switchboard is licensed under the MIT License.

See the LICENSE.md file for details.

TL;DR: You can use, modify, and distribute Switchboard freely, including for commercial purposes. No warranty is provided.

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (1)

Showing the top 1 NuGet packages that depend on SwitchboardApplicationProxy:

Package Downloads
View.Models

Database models, services, and supporting classes for for View AI.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
3.0.14 168 12/24/2025
3.0.13 172 12/24/2025
3.0.12 168 12/22/2025
3.0.11 1,791 11/1/2025
3.0.10 985 10/17/2025
3.0.9 144 10/17/2025
3.0.8 180 10/17/2025
3.0.7 503 10/13/2025
3.0.6 129 10/11/2025
3.0.5 173 10/9/2025
3.0.4 303 9/20/2025
3.0.3 1,323 6/18/2025
3.0.2 211 6/14/2025
3.0.0 344 6/11/2025
2.0.6 372 3/10/2025
2.0.5 168 1/22/2025
2.0.4 145 1/17/2025
2.0.3 142 1/17/2025
2.0.2 157 1/16/2025
2.0.1 140 1/16/2025
2.0.0 155 1/16/2025
1.0.17 167 12/15/2024
1.0.16 177 12/14/2024
1.0.15 158 12/13/2024
1.0.14 168 12/13/2024
1.0.12 160 12/13/2024
1.0.11 151 12/13/2024
1.0.10 152 12/13/2024
1.0.9 157 12/13/2024
1.0.7 158 12/11/2024
1.0.6 152 12/11/2024
1.0.5 160 12/10/2024
1.0.3 149 12/10/2024
1.0.2 167 12/10/2024
1.0.1 165 12/10/2024
1.0.0 162 12/5/2024

Add health checks and rate limiting