Swagger Node.js API Runner (Fixed)

raw JSON →
1.0.1 verified Thu Apr 23 auth: no javascript maintenance

`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.

error Error: Failed to initialize swagger-node-runner: Cannot read property 'type' of undefined (or similar 'Cannot read property' errors during startup)
cause Often caused by an invalid or malformed Swagger/OpenAPI definition file (YAML/JSON). The parser cannot correctly interpret a part of the schema.
fix
Validate your 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
cause `swagger-node-runner-fixed` requires an `appRoot` property in its configuration options to correctly locate controllers and other application resources.
fix
Ensure your configuration object passed to swaggerRunner.run() includes appRoot: __dirname or the absolute path to your application's root directory.
error TypeError: Cannot find module 'swagger-tools'
cause This error typically occurs if you're trying to use code or configurations designed for older versions of `swagger-node-runner` (pre-v0.6.0) that relied on `swagger-tools`, with the `swagger-node-runner-fixed` package which uses `Sway`.
fix
Update your code and configurations to be compatible with 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'
cause The configured path to your Swagger/OpenAPI definition file is incorrect, or the file does not exist at the specified location.
fix
Double-check the 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)
cause This indicates a mismatch between the `operationId` specified in your Swagger/OpenAPI definition and the actual function name exported by your controller module, or that the controller file is not found.
fix
Ensure the 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.
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.
fix Ensure you are using `swagger-node-runner-fixed` for Node.js environments >= v10. Update your package.json to use `"swagger-node-runner-fixed": "^1.0.0"`.
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.
fix Review your code for any direct usage of `swagger-tools` functionality. Adapt configurations and custom logic to align with `Sway`'s API and structure. Refer to `Sway` documentation for updated approaches.
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.
fix Replace `cors` with `swagger-cors` in your application's middleware pipe configuration (e.g., in `config/default.yaml` or similar fitting definitions).
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.
fix To include error stacks, set `includeErrStack: true` under your `openapi-error` configuration in your application's config files (e.g., `config/default.yaml`).
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.
fix To catch validation errors, listen for the `'responseValidationError'` event on the runner instance. Example: `runner.on('responseValidationError', (err) => { console.error('Response validation error:', err); });`.
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.
fix Review your Swagger definition for `x-private: true` tags. If you wish to override this behavior, configure the `privateTags` setting for `swagger_raw` in your application's configuration.
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.
fix Consider migrating your security handler setup to use the `securityHandlersModule` setting within the `swagger_security` fitting configuration. This centralizes security logic lookup.
npm install swagger-node-runner-fixed
yarn add swagger-node-runner-fixed
pnpm add swagger-node-runner-fixed

This demonstrates initializing `swagger-node-runner-fixed` with an Express application, loading a local Swagger definition, and starting the server to serve API endpoints defined in the spec and routed to corresponding controllers.

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)`);
  });
});