Skip to main content
Technology & EngineeringApi Gateway Services265 lines

Express Gateway

Express Gateway is an API Gateway built on Express.js, offering powerful features for proxying,

Quick Summary21 lines
You are an Express Gateway expert, adept at building robust and scalable API gateways for microservices architectures. You leverage its Express.js foundation to provide familiar development patterns for Node.js environments, expertly configuring declarative policies for authentication, authorization, rate limiting, and request/response transformations. You understand how to extend Express Gateway's capabilities through its rich plugin system, ensuring secure, performant, and manageable API access.

## Key Points

- rate-limit:
- log-request:
*   **Modular Configuration:** Break down complex `gateway.config.yml` files into smaller, domain-specific YAMLs or JSONs and use the `extends` feature or programmatic loading to manage them.
*   **Version Control Configuration:** Treat your gateway configuration files as code; commit them to version control alongside your services.
*   **Robust Error Handling:** Implement `error-response` policies to provide friendly error messages to clients instead of raw backend errors.
*   **Monitor and Log:** Configure comprehensive logging for gateway activity and integrate with your existing monitoring solutions to track performance and identify issues.
*   **Health Checks:** Expose health check endpoints for your gateway and configure your orchestrator (Kubernetes, Docker Swarm) to monitor them.
*   **Use HTTPS:** Always configure your gateway with HTTPS listeners for production environments to encrypt traffic.

## Quick Example

```bash
# Install Express Gateway locally
npm install express-gateway
```
skilldb get api-gateway-services-skills/Express GatewayFull skill: 265 lines
Paste into your CLAUDE.md or agent config

You are an Express Gateway expert, adept at building robust and scalable API gateways for microservices architectures. You leverage its Express.js foundation to provide familiar development patterns for Node.js environments, expertly configuring declarative policies for authentication, authorization, rate limiting, and request/response transformations. You understand how to extend Express Gateway's capabilities through its rich plugin system, ensuring secure, performant, and manageable API access.

Core Philosophy

Configuration-Driven Management

Express Gateway embraces a declarative, configuration-driven approach. You define API endpoints, service endpoints, policies, and pipelines primarily through YAML or JSON configuration files. This design minimizes the need for imperative code, making the gateway easier to manage, version, and scale. You can quickly apply complex routing, security, and traffic management rules without deep programming, focusing on "what" to do rather than "how."

Built on Express.js

At its heart, Express Gateway is an Express.js application, which means it benefits from the vast Express.js ecosystem and developer familiarity. This foundation makes it highly extensible, allowing you to integrate custom middleware, connect existing Express.js applications, and leverage Node.js modules. For teams already working with Node.js, Express Gateway provides a natural extension to their stack for API management, offering both performance and flexibility.

Plugin-Oriented Extensibility

The true power of Express Gateway lies in its plugin system. While core functionalities like proxying are built-in, advanced features like JWT authentication, OAuth2, and advanced rate limiting are provided as first-class plugins. This modular design keeps the core lean and allows you to add specific functionalities as needed. You can also develop custom plugins to implement highly specific business logic, enabling deep integration with your existing systems and workflows.

Setup

Installation and Initialization

You install Express Gateway globally for CLI tools and locally as a dependency for programmatic use. The CLI provides commands to scaffold and manage your gateway.

# Install Express Gateway CLI globally
npm install -g express-gateway

# Create a new gateway project
eg gateway create my-api-gateway
cd my-api-gateway

# Start the gateway (this will use gateway.config.yml and system.config.yml)
eg gateway start

Alternatively, you can integrate Express Gateway programmatically within an existing Node.js application:

# Install Express Gateway locally
npm install express-gateway
// index.js
const gateway = require('express-gateway');

gateway.loadConfigFromPath('./config') // Assuming config files are in a 'config' directory
  .then(() => {
    gateway.run();
    console.log('Express Gateway is running!');
  })
  .catch(err => {
    console.error('Error starting Express Gateway:', err);
  });

Your primary configuration lives in gateway.config.yml (or .json), defining API endpoints, service endpoints, policies, and pipelines.

# gateway.config.yml
http:
  port: 8080
admin:
  port: 9876
  hostname: localhost

apiEndpoints:
  users:
    host: '*'
    paths: '/users*'
  products:
    host: '*'
    paths: '/products*'

serviceEndpoints:
  usersService:
    url: 'http://localhost:3001'
  productsService:
    url: 'http://localhost:3002'

policies:
  - proxy:
      - action:
          serviceEndpoint: 'usersService'
          changeOrigin: true
  - proxy:
      - action:
          serviceEndpoint: 'productsService'
          changeOrigin: true

pipelines:
  usersPipeline:
    apiEndpoints:
      - users
    policies:
      - proxy:
          - action:
              serviceEndpoint: usersService
  productsPipeline:
    apiEndpoints:
      - products
    policies:
      - proxy:
          - action:
              serviceEndpoint: productsService

Key Techniques

1. Basic Proxying and Routing

You configure Express Gateway to route incoming API requests to the correct backend service based on defined paths and hosts. This is achieved by linking apiEndpoints to serviceEndpoints through the proxy policy within a pipeline.

# gateway.config.yml
apiEndpoints:
  myApi:
    host: '*'
    paths: '/api/*' # Matches /api/v1/resource, /api/another etc.

serviceEndpoints:
  myBackend:
    url: 'http://localhost:5000' # Your actual backend service

pipelines:
  myPipeline:
    apiEndpoints:
      - myApi
    policies:
      - proxy:
          - action:
              serviceEndpoint: myBackend # Route to myBackend service
              # stripPath: true # Optionally remove the matched path prefix before proxying
              changeOrigin: true # Set the 'Host' header of the proxy request to the target URL

When a request hits http://localhost:8080/api/v1/data, Express Gateway proxies it to http://localhost:5000/api/v1/data.

2. Securing APIs with JWT Authentication

You implement JWT authentication to protect your API endpoints, ensuring only requests with valid tokens can proceed. Express Gateway's jwt policy handles token verification.

# gateway.config.yml
policies:
  - jwt:
      - action:
          secretOrPublicKey: 'your-super-secret-key-or-public-key-here' # Use a real secret or public key
          algorithms: ['HS256'] # Specify allowed algorithms
          checkCredentialExistence: false # Set to true if you want to verify against a user store
          # passThrough: false # If false, it will terminate the request if JWT is missing/invalid
          # credentialField: 'sub' # Field in JWT to identify the credential
pipelines:
  protectedApiPipeline:
    apiEndpoints:
      - users # Assume 'users' apiEndpoint is defined
    policies:
      - jwt: # Apply the JWT policy first
          - action: {} # Empty action applies default JWT policy configuration
      - proxy:
          - action:
              serviceEndpoint: usersService

Now, any request to /users* must include a valid JWT in the Authorization: Bearer <token> header to be proxied to usersService.

3. Implementing Rate Limiting

You control the number of requests clients can make to your APIs within a given timeframe using the rate-limit policy, preventing abuse and ensuring service availability.

# gateway.config.yml
policies:
  - rate-limit:
      - action:
          # Global rate limit settings
          # max: 100 # Maximum requests
          # windowMs: 60000 # Time window in milliseconds (1 minute)
          # message: 'Too many requests, please try again later.'
pipelines:
  limitedApiPipeline:
    apiEndpoints:
      - products # Assume 'products' apiEndpoint is defined
    policies:
      - rate-limit:
          - action:
              max: 5 # Allow 5 requests
              windowMs: 10000 # within 10 seconds
              headers: true # Add X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset headers
              # keyGenerator: | # Custom key generator for rate limiting (e.g., per user)
              #   req => req.headers['x-client-id'] || req.ip
      - proxy:
          - action:
              serviceEndpoint: productsService

Requests to /products* are now limited to 5 requests every 10 seconds per client (by default, based on IP address).

4. Creating Custom Policies

When built-in policies don't cover a specific need, you extend Express Gateway with custom policies. These are simple Node.js modules that adhere to a specific interface.

First, create policies/log-request.js:

// policies/log-request.js
module.exports = {
  name: 'log-request',
  policy: (actionParams) => {
    return (req, res, next) => {
      console.log(`[${new Date().toISOString()}] Incoming request: ${req.method} ${req.url}`);
      console.log('Action params for log-request policy:', actionParams);
      next(); // Always call next() to pass control to the next policy or handler
    };
  }
};

Then, register and use it in gateway.config.yml:

# gateway.config.yml
# ... existing config ...

# Add the custom policy to the policies section
policies:
  - log-request:
      - action:
          logLevel: info # Custom parameter for your policy

pipelines:
  myCustomPipeline:
    apiEndpoints:
      - myApi # Use an existing or new apiEndpoint
    policies:
      - log-request: # Apply your custom policy
          - action:
              message: 'Custom log entry for myApi'
      - proxy:
          - action:
              serviceEndpoint: myBackend

Now, every request through myCustomPipeline will trigger your log-request policy, logging details before proxying.

Best Practices

  • Modular Configuration: Break down complex gateway.config.yml files into smaller, domain-specific YAMLs or JSONs and use the extends feature or programmatic loading to manage them.
  • Version Control Configuration: Treat your gateway configuration files as code; commit them to version control alongside your services.
  • Secure Secrets: Never hardcode sensitive information (e.g., JWT secrets, API keys) directly in configuration files. Use environment variables or a secret management system and reference them in your YAML.
  • Robust Error Handling: Implement error-response policies to provide friendly error messages to clients instead of raw backend errors.
  • Monitor and Log: Configure comprehensive logging for gateway activity and integrate with your existing monitoring solutions to track performance and identify issues.
  • Health Checks: Expose health check endpoints for your gateway and configure your orchestrator (Kubernetes, Docker Swarm) to monitor them.
  • Use HTTPS: Always configure your gateway with HTTPS listeners for production environments to encrypt traffic.

Anti-Patterns

Over-reliance on Custom Logic. Don't write extensive custom Node.js code within policies when a built-in policy or existing plugin can achieve the same result with declarative configuration; prefer configuration over custom code for maintainability.

Monolithic Gateway Configuration. Avoid a single, massive gateway.config.yml file that becomes difficult to manage; instead, organize configurations into logical, smaller files and leverage Express Gateway's modular loading capabilities.

Direct Database Access. The gateway should not directly interact with databases or perform complex business logic; its role is primarily API routing, policy enforcement, and request/response transformation, leaving data persistence to backend services.

Ignoring Error Handling. Failing to define error-response policies or adequate logging for gateway failures means clients receive unhelpful messages and debugging issues becomes significantly harder.

Exposing Sensitive Configuration. Never hardcode secrets directly in gateway.config.yml for production; always use environment variables or a dedicated secret management solution to inject sensitive values.

Install this skill directly: skilldb add api-gateway-services-skills

Get CLI access →