Socket
Book a DemoInstallSign in
Socket

@gravity-ui/expresskit-api

Package Overview
Dependencies
Maintainers
3
Versions
1
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@gravity-ui/expresskit-api

ExpressKit OpenApi Integration

latest
Source
npmnpm
Version
1.0.0
Version published
Maintainers
3
Created
Source

ExpressKit OpenApi Integration

This package provides OpenAPI/Swagger integration for ExpressKit, automatically generating API documentation from your route contracts and authentication handlers.

Quick Start

  • Add the integration to an existing ExpressKit project:

    npm install @gravity-ui/expresskit-api
    
  • Wrap your routes before passing them to ExpressKit:

    Simple approach (without global auth handlers):

import {
  ExpressKit,
  withContract,
  AppRoutes,
  RouteContract,
  AuthPolicy,
} from '@gravity-ui/expresskit';
import {NodeKit} from '@gravity-ui/nodekit';
import {z} from 'zod';
import {createOpenApiRegistry, bearerAuth, apiKeyAuth} from '@gravity-ui/expresskit-api';

const {registerRoutes} = createOpenApiRegistry({title: 'Super API'});

const apiKeyHandler = apiKeyAuth(
  'apiKeyAuth', // scheme name
  'header', // location: 'header', 'query', or 'cookie'
  'X-API-Key', // parameter name
  ['read:items'], // optional scopes
)(function authenticate(req, res, next) {
  const apiKey = req.headers['x-api-key'];

  if (apiKey !== 'valid_api_key') {
    res.status(401).json({error: 'Unauthorized: Invalid API key'});
    return;
  }

  next();
});

const CreateItemConfig = {
  operationId: 'createItem',
  summary: 'Create a new item',
  tags: ['Items'],
  request: {
    body: z.object({
      itemName: z.string().min(3, 'Item name must be at least 3 characters long'),
      quantity: z.number().int().positive('Quantity must be a positive integer'),
    }),
  },
  response: {
    content: {
      201: z.object({
        itemId: z.string(),
        itemName: z.string(),
        quantity: z.number().positive(),
      }),
    },
  },
} satisfies RouteContract;

const createItemHandler = withContract(CreateItemConfig)(async (req, res) => {
  const {itemName, quantity} = req.body;

  const newItem = {
    itemId: `item_${Date.now()}`,
    itemName,
    quantity,
  };

  res.sendTyped(201, newItem);
});

export const routes: AppRoutes = {
  'POST /items': {
    handler: createItemHandler,
    authHandler: apiKeyHandler,
    authPolicy: AuthPolicy.required,
  },
};

const app = new ExpressKit(nodekit, registerRoutes(routes, nodekit));

app.run(); // Open http://localhost:3030/api/docs

Using setup parameter (with global auth handlers support):

import {
  ExpressKit,
  withContract,
  AppRoutes,
  RouteContract,
  AuthPolicy,
} from '@gravity-ui/expresskit';
import {NodeKit} from '@gravity-ui/nodekit';
import {z} from 'zod';
import {createOpenApiRegistry, bearerAuth} from '@gravity-ui/expresskit-api';

const {registerRoutes} = createOpenApiRegistry({title: 'Super API'});

// Global auth handler configured in NodeKit
const globalAuthHandler = bearerAuth('jwtAuth')(function authenticate(req, res, next) {
  const token = req.headers.authorization?.replace('Bearer ', '');
  if (token !== 'valid_token') {
    res.status(401).json({error: 'Unauthorized'});
    return;
  }
  next();
});

const nodekit = new NodeKit({
  config: {
    appAuthHandler: globalAuthHandler,
    appAuthPolicy: AuthPolicy.required,
  },
});

const routes: AppRoutes = {
  'POST /items': {
    handler: createItemHandler,
    // No authHandler specified - will use global appAuthHandler
  },
};

// Use setup parameter to access nodekit context
const app = new ExpressKit(nodekit, registerRoutes(routes, nodekit));

app.run(); // Open http://localhost:3030/api/docs

Config

createOpenApiRegistry(config?: OpenApiRegistryConfig) tunes both the generated schema and the Swagger UI mount. Key options:

FieldDefaultDescription
title"API Documentation"Top-level title shown in the UI.
version"1.0.0"Populates info.version.
description"Generated API documentation"Short blurb under the title.
contactundefined{name, email, url} for ownership info.
licenseundefined{name, url} displayed in the footer.
servers[ { url: 'http://localhost:3030' } ]Servers array for the spec dropdown.
swaggerUi{}Passed straight to swagger-ui-express (customCss, explorer, themes, …).
enabledtrueConvenience flag—skip calling registerRoutes if you want to hide docs.
path'/api/docs'Mount path for Swagger UI; value is used as-is.
swaggerJsonPathundefinedPath relative to mount path where OpenAPI schema is served as JSON. When set, Swagger UI loads the schema from this endpoint instead of embedding it directly.

Usage example:

const {registerRoutes} = createOpenApiRegistry({
  title: 'Super API',
  description: 'Internal platform endpoints',
  servers: [{url: 'https://api.example.com'}],
  swaggerUi: {
    explorer: true,
    customCss: '.topbar { display: none; }',
  },
});

Using swaggerJsonPath for async schema loading:

const {registerRoutes} = createOpenApiRegistry({
  title: 'Super API',
  path: '/api/docs',
  swaggerJsonPath: '/swagger.json', // Relative to mount path
});

// The schema will be available at /api/docs/swagger.json
// Swagger UI will load it asynchronously from this endpoint

Security Schemes for OpenAPI Documentation

ExpressKit supports automatic generation of security requirements in OpenAPI documentation based on the authentication handlers used in your routes.

Features

  • HOC Wrappers: withSecurityScheme allows you to add security metadata to any authentication handler.
  • Predefined Security Schemes: Ready-to-use wrappers for common authentication types:
    • bearerAuth: JWT/Bearer token authentication
    • apiKeyAuth: API key authentication
    • basicAuth: Basic authentication
    • oauth2Auth: OAuth2 authentication
    • oidcAuth: OpenID Connect authentication
  • Automatic Documentation: Security requirements are automatically included in OpenAPI documentation.

Basic Usage

import {bearerAuth} from 'expresskit';
import jwt from 'jsonwebtoken';

// Add OpenAPI security scheme metadata to your auth handler
const jwtAuthHandler = bearerAuth('myJwtAuth')(function authenticate(req, res, next) {
  // Your authentication logic here
  next();
});

// Use in routes
const routes = {
  'GET /api/protected': {
    handler: protectedRouteHandler,
    authHandler: jwtAuthHandler,
  },
};

Available Security Scheme Types

Bearer Token Authentication

const jwtAuthHandler = bearerAuth(
  'jwtAuth', // scheme name in OpenAPI docs
  ['read:users', 'write:users'], // optional scopes
)(authFunction);

API Key Authentication

const apiKeyHandler = apiKeyAuth(
  'apiKeyAuth', // scheme name
  'header', // location: 'header', 'query', or 'cookie'
  'X-API-Key', // parameter name
  ['read', 'write'], // optional scopes
)(authFunction);

Basic Authentication

const basicAuthHandler = basicAuth(
  'basicAuth', // scheme name
  ['read', 'write'], // optional scopes
)(authFunction);

OAuth2 Authentication

const oauth2Handler = oauth2Auth(
  'oauth2Auth', // scheme name
  {
    implicit: {
      authorizationUrl: 'https://example.com/oauth/authorize',
      scopes: {
        read: 'Read access',
        write: 'Write access',
      },
    },
  },
  ['read', 'write'], // optional scopes for this specific handler
)(authFunction);

OpenID Connect Authentication

const oidcHandler = oidcAuth(
  'oidcAuth', // scheme name
  'https://example.com/.well-known/openid-configuration',
  ['profile', 'email'], // optional scopes
)(authFunction);

Custom Security Schemes

If you need a custom security scheme, you can use the withSecurityScheme function directly:

import {withSecurityScheme} from 'expresskit';

const customAuthHandler = withSecurityScheme({
  name: 'myCustomScheme',
  scheme: {
    type: 'http',
    scheme: 'digest',
    description: 'Digest authentication',
  },
  scopes: ['read', 'write'],
})(authFunction);

Styling Swagger UI

Customize the Swagger UI via swaggerUi options or by bringing in theme helpers such as swagger-themes:

import {SwaggerTheme, SwaggerThemeNameEnum} from 'swagger-themes';

const theme = new SwaggerTheme();
const {registerRoutes} = createOpenApiRegistry({
  swaggerUi: {
    explorer: true,
    customCss: theme.getBuffer(SwaggerThemeNameEnum.DARK),
  },
});

See src/example/index.ts for a more elaborate setup that combines authentication examples with custom styling.

FAQs

Package last updated on 24 Dec 2025

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts