npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@oriolrius/node-red-api-gateway

v0.6.4

Published

Node-RED nodes for API gateway functionality

Readme

@oriolrius/node-red-api-gateway

A comprehensive Node-RED node package for building enterprise-grade REST APIs with built-in support for authentication, authorization, validation, caching, rate limiting, and OpenAPI documentation.

Features

  • API Server: Fastify-powered HTTP server with automatic OpenAPI spec generation
  • Endpoint Definition: Declarative API endpoint configuration with JSON Schema validation
  • Authentication: OAuth2/OpenID Connect via Keycloak integration
  • Authorization: Role/scope-based access control with OPA (Open Policy Agent) support
  • Validation: Request/response validation with JSON Schema
  • Pagination: Offset-based and cursor-based pagination
  • Filtering & Sorting: Configurable field filtering and sorting with SQL clause generation
  • Rate Limiting: Token bucket algorithm with per-IP, per-user, or custom key strategies
  • Caching: Response caching with ETag support and configurable TTL
  • Error Handling: RFC 7807 Problem Details format
  • Metrics: Prometheus metrics endpoint for monitoring
  • Logging: Structured JSON logging with Pino

Installation

From npm

cd ~/.node-red
npm install @oriolrius/node-red-api-gateway

For Development

cd ~/.node-red
npm install /path/to/node-red-api-gateway

Or using npm link:

# In the node-red-api-gateway directory
npm link

# In your Node-RED user directory
cd ~/.node-red
npm link @oriolrius/node-red-api-gateway

Quick Start

1. Basic API Setup

  1. Drag an apigw-config node onto the canvas and configure:

    • API Version: v1
    • Base Path: /api
    • OpenAPI Title: My API
  2. Drag an apigw-server node and configure:

    • Port: 3000
    • Config: Select your apigw-config node
    • Enable Swagger UI: true
  3. Drag an apigw-endpoint node and configure:

    • Path: /hello
    • Method: GET
    • Server: Select your apigw-server node
  4. Connect a function node to handle the request:

msg.res.json({ message: "Hello, World!" });
return null;
  1. Deploy and access:
    • API: http://localhost:3000/api/v1/hello
    • Swagger UI: http://localhost:3000/docs
    • OpenAPI Spec: http://localhost:3000/openapi.json

2. Import Example Flows

The package includes several example flows demonstrating different features:

  1. In Node-RED, click the menu (hamburger icon)
  2. Select Import > Examples > @oriolrius/node-red-api-gateway
  3. Choose an example:
    • Basic CRUD API - Complete CRUD operations for a products API
    • OAuth2 Authenticated API - Keycloak authentication with role-based access
    • OPA Protected API - Policy-based access control with Open Policy Agent
    • Pagination & Filtering - Advanced list operations with pagination and filtering

Nodes

apigw-config

Configuration node for centralized settings shared across apigw-server and apigw-endpoint nodes.

Database Configuration:

  • Database type (PostgreSQL, MSSQL, MySQL, etc.)
  • Connection pooling settings
  • Credentials (stored securely)

OAuth2/Keycloak Configuration:

  • Keycloak URL and realm
  • Client ID and secret
  • JWT validation settings (issuer, audience, clock tolerance)

OPA Configuration:

  • OPA server URL
  • Policy path
  • Cache TTL and timeout settings

API Settings:

  • Version string and base path
  • OpenAPI metadata (title, description, contact, license)

Logging:

  • Log level (debug, info, warn, error)
  • Output format (console, file)
  • Header redaction

apigw-server

HTTP server node that hosts your API endpoints.

Configuration:

  • Host and port
  • Reference to apigw-config node
  • OpenAPI specification endpoint (/openapi.json)
  • Swagger UI documentation (/docs)
  • Prometheus metrics endpoint (/metrics)

Features:

  • Automatic route registration from apigw-endpoint nodes
  • Route conflict detection
  • Graceful shutdown

apigw-endpoint

Individual API endpoint definition node.

Core Settings:

  • HTTP method (GET, POST, PUT, DELETE, PATCH, HEAD, OPTIONS)
  • Path with parameters (e.g., /users/:id)
  • Success status code
  • Response content type

Validation:

  • Body schema (JSON Schema)
  • Query parameter schema
  • Path parameter schema
  • Response schemas (for OpenAPI documentation)

Authorization:

  • Required scopes/roles
  • Scope operator (AND/OR)

CRUD Operations:

  • Operation type (list, get, create, update, delete)
  • Table name and primary key
  • Auto-generate SQL templates

Pagination:

  • Style: offset-based or cursor-based
  • Default and maximum page size

Filtering & Sorting:

  • Configurable filterable fields
  • Configurable sortable fields
  • Default sort field and direction

Transformation:

  • Request transformation (JSONata expression)
  • Response transformation (JSONata expression)
  • Field mappings

Rate Limiting:

  • Requests per time window
  • Key type (IP, user, API key, custom)

Caching:

  • TTL (time to live)
  • Cache key strategy
  • Vary headers
  • ETag support

Error Handling:

  • Error format (RFC 7807, generic, custom)
  • Stack trace inclusion (dev mode)
  • Custom error code mappings

Examples

Basic CRUD Endpoint

// In your function node connected to an apigw-endpoint
const products = [
  { id: 1, name: "Widget", price: 29.99 },
  { id: 2, name: "Gadget", price: 49.99 }
];

// List endpoint
msg.res.json({
  data: products,
  total: products.length
});
return null;

Request Validation

Configure the apigw-endpoint with a body schema:

{
  "type": "object",
  "properties": {
    "name": { "type": "string", "minLength": 1 },
    "price": { "type": "number", "minimum": 0 }
  },
  "required": ["name", "price"]
}

Invalid requests automatically return 400 errors with validation details.

OAuth2 Protected Endpoint

  1. Configure apigw-config with Keycloak settings
  2. Set requiredScopes on apigw-endpoint (e.g., admin, user:write)
  3. Access user info in your function:
const auth = msg.req.auth;
if (auth.authenticated) {
  console.log('User:', auth.preferredUsername);
  console.log('Roles:', auth.roles);
}

Pagination

Enable pagination on list endpoints:

// Pagination context is populated by apigw-endpoint
const { page, limit, offset } = msg.pagination || {};

// Query database with pagination
const results = await db.query(
  `SELECT * FROM products LIMIT ${limit} OFFSET ${offset}`
);
const total = await db.query('SELECT COUNT(*) FROM products');

// Use endpoint's helper to generate metadata
const paginationMeta = msg.endpoint.generatePaginationMeta(
  msg.pagination,
  { total: total[0].count, results: results.length }
);

msg.res.json({
  data: results,
  pagination: paginationMeta
});

Rate Limiting

Enable rate limiting on apigw-endpoint:

  • Requests: 100
  • Window: 60000 (1 minute)
  • Key Type: ip (or user for per-user limits)

Rate limit info is available in msg.rateLimit:

console.log('Remaining requests:', msg.rateLimit.remaining);

Response Caching

Enable caching on apigw-endpoint:

  • TTL: 30000 (30 seconds)
  • Key Strategy: full (includes query string)
  • Vary Headers: authorization (for user-specific caching)

The cache context is available in msg.cache:

if (msg.cache.hit) {
  console.log('Cache hit! Age:', msg.cache.age);
}

Development

Prerequisites

  • Node.js >= 20.0.0
  • npm >= 8.0.0

Setup

npm install

Running Tests

# Run unit tests
npm test

# Run tests in watch mode
npm run test:watch

Running End-to-End Tests

# Start the Docker stack (Node-RED, Keycloak, OPA, SQL Server)
npm run docker:e2e:up

# Run e2e tests
npm run test:e2e

# Stop the Docker stack
npm run docker:e2e:down

Linting

# Check for linting errors
npm run lint

# Fix linting errors automatically
npm run lint:fix

Development Node-RED

# Launch a development Node-RED instance
npm run dev

Scripts

Utility scripts are located in the scripts/ directory. See scripts/README.md for details.

Certificate Management

Download SSL certificates from Nginx Proxy Manager for e2e tests:

./scripts/download-apigw-cert.sh

This script uses npm-cli via uvx to download certificates and only updates files if they differ.

Project Structure

node-red-api-gateway/
├── nodes/                     # Node-RED nodes
│   ├── api-config.js/html    # Configuration node (apigw-config)
│   ├── api-server.js/html    # HTTP server node (apigw-server)
│   ├── api-endpoint.js/html  # Endpoint definition node (apigw-endpoint)
│   └── icons/                # Node icons
├── lib/                       # Shared utility modules
│   ├── path-utils.js         # Path manipulation
│   ├── schema-validator.js   # JSON Schema validation
│   ├── rate-limiter.js       # Token bucket rate limiting
│   ├── response-cache.js     # Response caching
│   ├── error-handler.js      # Error handling
│   ├── pagination.js         # Pagination helpers
│   ├── filtering-sorting.js  # Filter/sort parsing
│   ├── crud-generator.js     # SQL generation
│   ├── keycloak-client.js    # OAuth2/JWT validation
│   ├── opa-client.js         # OPA integration
│   ├── openapi-generator.js  # OpenAPI spec generation
│   ├── openapi-parser.js     # OpenAPI import
│   ├── logger.js             # Pino logging
│   └── metrics-collector.js  # Prometheus metrics
├── examples/                  # Example flows
├── scripts/                   # Utility scripts (see scripts/README.md)
├── tests/                     # Test suites
│   ├── unit/                 # Unit tests
│   └── e2e/                  # End-to-end tests
└── package.json

API Reference

Message Properties

When a request hits an apigw-endpoint, the following properties are available on msg:

| Property | Type | Description | |----------|------|-------------| | msg.req | Object | Request object (method, url, headers, body, params, query) | | msg.req.auth | Object | Authentication info (if OAuth2 enabled) | | msg.res | Object | Response helpers (json, send, status, set, end) | | msg.endpoint | Object | Endpoint configuration | | msg.pagination | Object | Parsed pagination params (if enabled) | | msg.filtering | Object | Parsed filters and WHERE clause (if enabled) | | msg.sorting | Object | Parsed sorts and ORDER BY clause (if enabled) | | msg.crud | Object | CRUD operation context (if configured) | | msg.cache | Object | Cache status (hit, key, age) | | msg.rateLimit | Object | Rate limit status (allowed, remaining, limit) |

Response Helpers

// Send JSON response
msg.res.json({ data: "value" });

// Set status code
msg.res.status(201).json({ id: 1 });

// Set headers
msg.res.set('X-Custom-Header', 'value');

// End without body
msg.res.status(204).end();

License

MIT

Contributing

Contributions are welcome! Please read our contributing guidelines and submit pull requests to the main repository.