The primary reason you’d pick one API gateway over another for REST, HTTP, or WebSocket APIs isn’t about protocol differences, but about which gateway excels at managing the state and connection lifecycles that each protocol implies.

Let’s look at what this actually means in practice. Imagine we have a simple REST API that returns the current time.

// GET /time
{
  "timestamp": 1678886400
}

And a WebSocket API that streams real-time stock prices.

// Client connects to ws://example.com/stocks
// Server pushes:
{
  "symbol": "AAPL",
  "price": 170.50
}
// Server pushes:
{
  "symbol": "GOOG",
  "price": 95.20
}

An API Gateway sits in front of these, handling routing, authentication, rate limiting, etc.

REST APIs: Stateless Transactions

REST APIs are fundamentally about stateless, request-response interactions. Each request from a client to a server must contain all the information necessary to understand and fulfill that request. The server doesn’t retain any client context between requests.

An API Gateway for REST needs to efficiently:

  1. Route: Direct incoming HTTP requests to the correct backend service.
  2. Authenticate/Authorize: Verify the client’s identity and permissions for each request.
  3. Transform: Modify requests/responses if necessary (e.g., add headers, change formats).
  4. Cache: Store responses to common requests to reduce backend load.

Example Configuration (Conceptual - using Kong API Gateway syntax):

# Kong configuration snippet for a REST API
plugins:
  - name: request-transformer
    config:
      add:
        headers:
          - "X-Forwarded-For:$remote_addr"
  - name: acl
    config:
      allow:
        - authenticated_consumer_group_A
        - authenticated_consumer_group_B
routes:
  - name: time-api-route
    paths:
      - /time
    methods:
      - GET
    strip_path: true
    service: time-service
services:
  - name: time-service
    url: http://time-service.internal:8080

Here, the gateway receives a GET /time request, adds the client’s IP to X-Forwarded-For, checks if the consumer is in an allowed group, and then forwards it to http://time-service.internal:8080/time. The crucial part is that for the next request, the gateway (and backend) starts fresh, without knowledge of the previous one.

HTTP APIs: A Broader Category

"HTTP APIs" is a bit of a catch-all. It often refers to APIs that use HTTP as the transport but might not strictly adhere to REST principles. This could include RPC-style APIs over HTTP (like gRPC-web) or simply any service exposed via HTTP. The gateway’s role here is similar to REST: routing, security, transformation. The key is that the gateway needs to understand HTTP semantics well.

WebSocket APIs: Stateful, Persistent Connections

WebSockets are fundamentally different. They establish a persistent, full-duplex communication channel over a single TCP connection. This means the server (and anything in between, like an API Gateway) needs to manage the state of these connections.

An API Gateway for WebSockets needs to:

  1. Upgrade Handling: Gracefully manage the HTTP Upgrade request that initiates a WebSocket connection.
  2. Connection Management: Keep track of active connections, their origins, and associated client identities.
  3. Message Routing: Forward messages between clients and backend services. This is not a simple request-response; it’s message-stream routing.
  4. Stateful Authentication/Authorization: Often, authentication is done once during the handshake, and subsequent messages rely on the established connection’s trust.
  5. Scalability: Handle potentially millions of long-lived connections efficiently.

Example Configuration (Conceptual - using Nginx as a reverse proxy/gateway for WebSockets):

# Nginx configuration snippet for WebSocket API
http {
  # ... other http settings ...

  upstream websocket_backend {
    server websocket-service.internal:9000;
  }

  server {
    listen 80;
    server_name example.com;

    location /stocks {
      proxy_pass http://websocket_backend;
      proxy_http_version 1.1;
      proxy_set_header Upgrade $http_upgrade;
      proxy_set_header Connection "upgrade";
      proxy_set_header Host $host;
      proxy_set_header X-Real-IP $remote_addr;
      proxy_read_timeout 86400; # Keep connection alive for a long time
      proxy_connect_timeout 7s;
    }
  }
}

When a client sends an Upgrade request to /stocks, Nginx recognizes the Upgrade header, sets up a persistent connection to websocket-service.internal:9000, and forwards all subsequent messages back and forth. The gateway isn’t just proxying requests; it’s managing the life of the connection.

The Key Differentiator: Connection State Management

The core difference in choosing an API Gateway for these protocols boils down to how well it handles connection state.

  • REST/HTTP: Gateways for these protocols are optimized for high-throughput, stateless request-response cycles. They excel at caching, rate limiting individual requests, and transforming ephemeral HTTP messages. Tools like Nginx, HAProxy, Traefik, or managed services like AWS API Gateway (for REST/HTTP) are strong here.
  • WebSocket: Gateways for WebSockets need to be efficient at managing potentially millions of long-lived, stateful connections. They must handle connection lifecycle events (connect, disconnect, message), maintain client identity across messages, and route data bidirectionally. Solutions like Nginx (with proper configuration), Envoy, or specialized WebSocket gateways (e.g., Socket.IO’s own adapter, or custom solutions built on message queues) are better suited.

The most surprising truth is that many gateways designed for high-performance HTTP/REST can also handle WebSockets, but their configuration and underlying architecture are optimized for fundamentally different traffic patterns. A gateway that can process 100,000 REST requests per second might struggle to maintain 10,000 persistent WebSocket connections, and vice-versa. The "state" being managed is the critical difference: ephemeral request state vs. persistent connection state.

When you configure a WebSocket endpoint, you’re not just forwarding HTTP. You’re telling the gateway to become a stateful intermediary for a TCP stream. This involves setting timeouts for connection persistence (like proxy_read_timeout 86400; in Nginx), ensuring the Upgrade headers are correctly passed, and often configuring backend services to be inherently stateful themselves. The gateway needs to hold onto the connection, ready to shuttle messages, rather than just fulfilling a single request and forgetting about it. This means the gateway’s internal data structures and event loops are structured differently to accommodate this persistent state.

If you’re building a system that mixes REST and WebSockets, you’ll likely need an API Gateway that supports both, but critically, it must have distinct configuration profiles or underlying architectures to handle the state management requirements of each protocol effectively. The next challenge you’ll face is managing the security and observability of these stateful WebSocket connections.

Want structured learning?

Take the full Apigateway course →