4.12.0-beta.5 • Published 3 years ago

koa-openapi-validator v4.12.0-beta.5

Weekly downloads
11
License
MIT
Repository
github
Last release
3 years ago

🦋 koa-openapi-validator

npm.io npm.io npm.io All Contributors Coverage Status Codacy Badge npm.io Gitpod Ready-to-Code npm.io

An OpenApi validator for Koa that automatically validates API requests using an OpenAPI 3 specification.

Install

npm install koa-openapi-validator@4.12.0-beta.3

Usage

Code

const OpenApiValidator = require('koa-openapi-validator');
app.use(
  OpenApiValidator.middleware({
    apiSpec: './openapi.yml',
    // additional options
  }),
);

Example

const koa = require('koa');
const koaRouter = require('koa-router');
const koaBodyParser = require('koa-bodyparser');
const OpenApiValidator = require('koa-openapi-validator');

const app = new koa();
const router = new koaRouter();

// 1. install body parser for multipart
app.use(koaBodyParser({}))

// 2. define your routes
router.get('koala', '/v1/pets', (ctx) => {
  ctx.body = {
    message: 'Welcome! To the Koala Book of Everything!',
  };
});

// 3. define error middleware and an error response
app.use(async (ctx, next) => {
  try {
    await next();
  } catch (err) {
    // console.error(err);
    ctx.status = err.statusCode || err.status || 500;
    ctx.body = {
      message: err.message,
      errors: err.errors ?? [],
    };
  }
});

// 4. configure the koa-openapi-validator
app.use(
  OpenApiValidator.middleware({
    apiSpec: './openapi.yml',
  }),
);

app.use(router.routes()).use(router.allowedMethods());

app.listen(1234, () => console.log('running on port 1234'));

Options

Options are provided via the options object. Options take the following form:

OpenApiValidator.middleware({
  apiSpec: './openapi.yaml',
  validateRequests: true,
  validateFormats: 'fast',
  formats: [{
    name: 'my-custom-format',
    type: 'string' | 'number',
    validate: (value: any) => boolean,
  }],
  unknownFormats: ['phone-number', 'uuid'],
  ignorePaths: /.*\/pets$/,
  $refParser: {
    mode: 'bundle'
  }
});

▪️ apiSpec (required)

Specifies the path to an OpenAPI 3 specification or a JSON object representing the OpenAPI 3 specificiation

apiSpec: './path/to/my-openapi-spec.yaml';

or

  apiSpec: {
  openapi: '3.0.1',
  info: {...},
  servers: [...],
  paths: {...},
  components: {
    responses: {...},
    schemas: {...}
  }
}

▪️ validateRequests (optional)

Determines whether the validator should validate requests.

  • true (default) - validate requests.
  • false - do not validate requests.
  • { ... } - validate requests with options

    allowUnknownQueryParameters:

    • true - enables unknown/undeclared query parameters to pass validation
    • false - (default) fail validation if an unknown query parameter is present

    For example:

    validateRequests: {
      allowUnknownQueryParameters: true;
    }

    allowUnknownQueryParameters is set for the entire validator. It can be overwritten per-operation using a custom property x-allow-unknown-query-parameters.

    For example to allow unknown query parameters on ONLY a single endpoint:

    paths:
      /allow_unknown:
        get:
          x-allow-unknown-query-parameters: true
          parameters:
            - name: value
              in: query
              schema:
                type: string
          responses:
            200:
              description: success

    coerceTypes:

    Determines whether the validator will coerce the request body. Request query and path params, headers, cookies are coerced by default and this setting does not affect that.

    Options:

    • true - coerce scalar data types.
    • false - (default) do not coerce types. (more strict, safer)
    • "array" - in addition to coercions between scalar types, coerce scalar data to an array with one element and vice versa (as required by the schema).

    For example:

    validateRequests: {
      coerceTypes: true;
    }

▪️ formats (optional)

Defines a list of custome formats.

  • [{ ... }] - array of custom format objects. Each object must have the following properties:
    • name: string (required) - the format name
    • validate: (v: any) => boolean (required) - the validation function
    • type: 'string' | 'number' (optional) - the format's type

e.g.

formats: [
  {
    name: 'my-three-digit-format',
    type: 'number',
    // validate returns true the number has 3 digits, false otherwise
    validate: (v) => /^\d{3}$/.test(v.toString()),
  },
  {
    name: 'my-three-letter-format',
    type: 'string',
    // validate returns true the string has 3 letters, false otherwise
    validate: (v) => /^[A-Za-z]{3}$/.test(v),
  },
];

Then use it in a spec e.g.

my_property:
  type: string
  format: my-three-letter-format'

▪️ validateFormats (optional)

Specifies the strictness of validation of string formats.

  • "fast" (default) - only validate syntax, but not semantics. E.g. 2010-13-30T23:12:35Z will pass validation eventhough it contains month 13.
  • "full" - validate both syntax and semantics. Illegal dates will not pass.
  • false - do not validate formats at all.

▪️ unknownFormats (optional)

Defines how the validator should behave if an unknown or custom format is encountered.

  • true (default) - When an unknown format is encountered, the validator will report a 400 error.
  • [string] (recommended for unknown formats) - An array of unknown format names that will be ignored by the validator. This option can be used to allow usage of third party schemas with format(s), but still fail if another unknown format is used. e.g.

    unknownFormats: ['phone-number', 'uuid'];
  • "ignore" - to log warning during schema compilation and always pass validation. This option is not recommended, as it allows to mistype format name and it won't be validated without any error message.

▪️ ignorePaths (optional)

Defines a regular expression or function that determines whether a path(s) should be ignored. If it's a regular expression, any path that matches the regular expression will be ignored by the validator. If it's a function, it will ignore any paths that returns a truthy value.

The following ignores any path that ends in /pets e.g. /v1/pets. As a regular expression:

ignorePaths: /.*\/pets$/

or as a function:

ignorePaths: (path) => path.endsWith('/pets')

▪️ \$refParser.mode (optional)

Determines how JSON schema references are resolved by the internal json-schema-ref-parser. Generally, the default mode, bundle is sufficient, however if you use escape characters in \$refs, dereference is necessary.

  • bundle (default) - Bundles all referenced files/URLs into a single schema that only has internal $ref pointers. This eliminates the risk of circular references, but does not handle escaped characters in $refs.
  • dereference - Dereferences all $ref pointers in the JSON Schema, replacing each reference with its resolved value. Introduces risk of circular $refs. Handles escape characters in \$refs)

See this issue for more information.

e.g.

$refParser: {
  mode: 'bundle';
}

Related Projects

License

MIT