Swagger Node.js API Runner (Fixed)
raw JSON →`swagger-node-runner-fixed` is a maintained fork of the original `apigee-127/swagger-node-runner`, primarily addressing compatibility issues with Node.js versions greater than 10. It serves as a comprehensive loader and middleware utility for building API projects based on Swagger/OpenAPI specifications, seamlessly integrating with popular Node.js web frameworks like Express, Restify, and Hapi. The package's current stable version is 1.0.1. Its core functionality involves interpreting a Swagger definition, applying various 'fittings' (middleware), and routing incoming requests to corresponding controllers based on the API specification. A significant architectural shift occurred in earlier versions (around v0.6.0 and v0.7.0), transitioning the underlying Swagger processing engine from `swagger-tools` to the more robust `Sway` library, which brought improved validation and schema capabilities. The project's release cadence is now infrequent, focusing on critical fixes and maintaining Node.js compatibility rather than extensive feature development.
Common errors
error Error: Failed to initialize swagger-node-runner: Cannot read property 'type' of undefined (or similar 'Cannot read property' errors during startup) ↓
swagger.yaml or swagger.json file rigorously using an online OpenAPI/Swagger validator. Pay close attention to syntax, indentation, and required fields. error Error: 'appRoot' is required ↓
swaggerRunner.run() includes appRoot: __dirname or the absolute path to your application's root directory. error TypeError: Cannot find module 'swagger-tools' ↓
Sway. Remove any direct dependencies or references to swagger-tools from your project. error Error: ENOENT: no such file or directory, stat './api/swagger/swagger.yaml' ↓
swaggerPath in your application's setup to ensure it correctly points to your swagger.yaml or swagger.json file. Verify the file's existence and permissions. error Error: Operation 'myOperationId' not found for path '/my-path' (or similar routing errors) ↓
x-swagger-router-controller and operationId in your Swagger definition precisely match the controller file name and exported function names respectively. Verify the controllers path in your swaggerRunner.run() configuration is correct. Warnings
breaking This package is a fork specifically created to provide compatibility with Node.js versions greater than 10. Original `swagger-node-runner` versions may not function correctly or at all on modern Node.js runtimes. ↓
breaking The underlying Swagger processing library `swagger-tools` was completely replaced by `Sway` in v0.6.0. If your application relied on direct interaction with `swagger-tools` APIs or its specific configuration options, these will no longer be available or compatible. ↓
breaking The `swagger-cors` fitting was introduced in v0.7.1 as a replacement for the generic `cors` fitting. Applications using `cors` in their middleware pipe might need to update. ↓
gotcha The `json_error_handler` fitting's behavior for including error stack traces in 500 responses is now controlled by the `includeErrStack` flag. By default, error stacks might not be included, potentially hindering debugging in development environments. ↓
gotcha Response validation changed in v0.6.4. It no longer overwrites API responses but instead emits a `'responseValidationError'` event. Applications expecting automatic response modification will need to implement an event listener. ↓
gotcha The `swagger_raw` fitting now supports hiding specific API paths or operations from the served Swagger documentation by tagging them with `x-private: true`. If not configured intentionally, parts of your API might be unexpectedly hidden. ↓
gotcha Security handlers can now be automatically looked up and installed using the `securityHandlersModule` setting in your configuration. Older programmatic approaches might be less efficient or harder to maintain. ↓
Install
npm install swagger-node-runner-fixed yarn add swagger-node-runner-fixed pnpm add swagger-node-runner-fixed Imports
- swaggerRunner wrong
import swaggerRunner from 'swagger-node-runner-fixed';correctconst swaggerRunner = require('swagger-node-runner-fixed'); - run
swaggerRunner.run(app, config, callback); - Swagger definitions (YAML/JSON)
const swaggerDoc = yaml.load(fs.readFileSync(swaggerPath, 'utf8'));
Quickstart
const express = require('express');
const app = express();
const swaggerRunner = require('swagger-node-runner-fixed');
const path = require('path');
const fs = require('fs');
const yaml = require('js-yaml');
const port = process.env.PORT || 3000;
const swaggerSpecPath = path.resolve(__dirname, './api/swagger/swagger.yaml');
const controllersPath = path.resolve(__dirname, './api/controllers');
// Ensure required directories exist for demonstration
if (!fs.existsSync(path.dirname(swaggerSpecPath))) fs.mkdirSync(path.dirname(swaggerSpecPath), { recursive: true });
if (!fs.existsSync(controllersPath)) fs.mkdirSync(controllersPath, { recursive: true });
// Minimal swagger.yaml for quickstart (create this file manually at ./api/swagger/swagger.yaml)
fs.writeFileSync(swaggerSpecPath, `swagger: "2.0"
info:
title: "My API"
version: "1.0.0"
basePath: /
paths:
/hello:
get:
operationId: helloWorld
responses:
200:
description: "OK"
schema:
type: string
`);
// Minimal controller (create this file manually at ./api/controllers/hello_world.js)
fs.writeFileSync(path.join(controllersPath, 'hello_world.js'), `module.exports = {
helloWorld: function(req, res) {
res.send('Hello from Swagger!');
}
};
`);
// Load the Swagger definition
const swaggerDoc = yaml.load(fs.readFileSync(swaggerSpecPath, 'utf8'));
const config = {
appRoot: __dirname, // Required for swagger-node-runner to find controllers
swagger: swaggerDoc,
controllers: controllersPath // Path to your API controllers
};
swaggerRunner.run(app, config, function(err) {
if (err) {
console.error('Failed to initialize swagger-node-runner:', err.message);
process.exit(1);
}
// swagger-node-runner-fixed will automatically attach middleware and routes
app.listen(port, () => {
console.log(`Server running on http://localhost:${port}`);
console.log(`Try: curl http://localhost:${port}/hello`);
console.log(`Swagger UI is typically available at http://localhost:${port}/docs (if configured via fittings)`);
});
});