Giter Club home page Giter Club logo

fastify-response-validation's Introduction

@fastify/response-validation

CI NPM version js-standard-style

A simple plugin that enables response validation for Fastify.
The use of this plugin will slow down your overall performance, so we suggest using it only during development.

Install

npm i @fastify/response-validation

Usage

You just need to register the plugin and you will have response validation enabled:

import fastify from 'fastify'

const app = fastify()

await app.register(require('@fastify/response-validation'))

app.route({
  method: 'GET',
  path: '/',
  schema: {
    response: {
      '2xx': {
        type: 'object',
        properties: {
          answer: { type: 'number' }
        }
      }
    }
  },
  handler: async (req, reply) => {
    return { answer: '42' }
  }
})

app.inject({
  method: 'GET',
  path: '/'
}, (err, res) => {
  if (err) throw err
  console.log(res.payload)
})

Different content types responses are supported by @fastify/response-validation, @fastify/swagger and fastify. Please use content for the response otherwise Fastify itself will fail to compile the schema:

{
  response: {
    200: {
      description: 'Description and all status-code based properties are working',
      content: {
        'application/json': {
          schema: { 
            name: { type: 'string' }, 
            image: { type: 'string' }, 
            address: { type: 'string' } 
          }
        }, 
        'application/vnd.v1+json': {
          schema: { 
            fullName: { type: 'string' }, 
            phone: { type: 'string' } 
          }
        }
      }
    }
  }
}

If you want to override the default ajv configuration, you can do that by using the ajv option:

// Default configuration:
//    coerceTypes: false
//    useDefaults: true
//    removeAdditional: true
//    allErrors: true

import responseValidator from '@fastify/response-validation'

// ... App setup

await fastify.register(responseValidator, {
  ajv: {
    coerceTypes: true
  }
})

You can also pass in an instance of ajv

// Default configuration:
//    coerceTypes: false
//    useDefaults: true
//    removeAdditional: true
//    allErrors: true

import responseValidator from '@fastify/response-validation'
import Ajv from 'ajv'

// ... App setup

const ajv = new Ajv()
await fastify.register(responseValidator, { ajv })

By default the response validation is enabled on every route that has a response schema defined. If needed you can disable it all together with responseValidation: false:

import responseValidator from '@fastify/response-validation'

// ... App setup
await fastify.register(responseValidator, {
  responseValidation: false
})

Alternatively, you can disable a specific route with the same option:

fastify.route({
  method: 'GET',
  path: '/',
  responseValidation: false,
  schema: {
    response: {
      '2xx': {
        type: 'object',
        properties: {
          answer: { type: 'number' }
        }
      }
    }
  },
  handler: async (req, reply) => {
    return { answer: '42' }
  }
})

Plugins

You can also extend the functionalities of the ajv instance embedded in this validator by adding new ajv plugins.

fastify.register(require('fastify-response-validation'), {
  ajv: {
    plugins: [
      require('ajv-formats'),
      [require('ajv-errors'), { singleError: false }]
      // Usage: [plugin, pluginOptions] - Plugin with options
      // Usage: plugin - Plugin without options
    ]
  }
})

License

MIT

fastify-response-validation's People

Contributors

climba03003 avatar committomaster avatar dancastillo avatar delvedor avatar dependabot[bot] avatar eomm avatar fdawgs avatar felixfbecker avatar is2ei avatar jsumners avatar mcollina avatar metcoder95 avatar nicobuzeta avatar sceccotti89 avatar sleepwalker avatar uzlopak avatar woh avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

fastify-response-validation's Issues

Supporting different content-type responses

Prerequisites

  • I have written a descriptive issue title
  • I have searched existing issues to ensure the feature has not already been requested

๐Ÿš€ Feature Proposal

This plugin does not support response validation in combination with different content types.

Motivation

While not supported by this plugin, both fastify and swagger support it already:

Example

The following setup is supported by @fastify/swagger(-ui), but does not work when used with the fastify response validation plugin:

    {
      schema: {
        body: Polygon,
        response: {
          200: {
            description: "Success",
            content: {
              "application/geo+json": {
                schema: FeatureCollection,
              },
            },
          },
      },
  }

Results are errors, but at the end of the day, it just does not seem to be intended.

ERROR (110): strict mode: unknown keyword: "application/geo+json"
    err: {
      "type": "Error",
      "message": "strict mode: unknown keyword: \"application/geo+json\"",
      "stack":
          Error: strict mode: unknown keyword: "application/geo+json"
              at checkStrictMode (/node_modules/@fastify/response-validation/node_modules/ajv/dist/compile/util.js:174:15)
              at checkUnknownRules (/node_modules/@fastify/response-validation/node_modules/ajv/dist/compile/util.js:32:13)
              at alwaysValidSchema (/node_modules/@fastify/response-validation/node_modules/ajv/dist/compile/util.js:19:5)
              at <anonymous> (/node_modules/@fastify/response-validation/node_modules/ajv/dist/vocabularies/applicator/properties.js:23:63)
              at Array.filter (<anonymous>)
              at Object.code (/node_modules/@fastify/response-validation/node_modules/ajv/dist/vocabularies/applicator/properties.js:23:37)
              at keywordCode (/node_modules/@fastify/response-validation/node_modules/ajv/dist/compile/validate/index.js:454:13)
              at <anonymous> (/node_modules/@fastify/response-validation/node_modules/ajv/dist/compile/validate/index.js:222:17)
              at CodeGen.code (/node_modules/@fastify/response-validation/node_modules/ajv/dist/compile/codegen/index.js:439:13)
              at CodeGen.block (/node_modules/@fastify/response-validation/node_modules/ajv/dist/compile/codegen/index.js:568:18)
    }
ERROR (62): schema is invalid: data/properties/description must be object,boolean
    err: {
      "type": "Error",
      "message": "schema is invalid: data/properties/description must be object,boolean",
      "stack":
          Error: schema is invalid: data/properties/description must be object,boolean
              at Ajv.validateSchema (/node_modules/@fastify/response-validation/node_modules/ajv/dist/core.js:266:23)
              at Ajv._addSchema /node_modules/@fastify/response-validation/node_modules/ajv/dist/core.js:460:18)
              at Ajv.compile (/node_modules/@fastify/response-validation/node_modules/ajv/dist/core.js:158:26)
              at buildHook /node_modules/@fastify/response-validation/index.js:46:37)
              at Object.onRoute (/node_modules/@fastify/response-validation/index.js:38:34)
              at Object.addNewRoute (/node_modules/fastify/lib/route.js:243:16)
              at Object.route (/node_modules/fastify/lib/route.js:217:19)
              at Object.prepareRoute (/node_modules/fastify/lib/route.js:150:18)
              at Object._post (/node_modules/fastify/fastify.js:258:34)
              [...]

Unknown format "float" is used in schema at path "..."

Prerequisites

  • I have written a descriptive issue title
  • I have searched existing issues to ensure it has not already been reported

Fastify version

3.17.0

Plugin version

0.1.0

Node.js version

16.2.0

Operating system

macOS

Operating system version (i.e. 20.04, 11.3, 10)

10.15.7

Description

Hi, I'm trying to use this plugin to validate the responses generated by my Fastify app. In addition to Fastify, in order to generate programmatically all the routes from an openapi specification, I'm using fastify-openapi-glue.

Each time I try to run my app I get the following error:
unknown format "float" is used in schema at path "..."

In order to solve this issue i tried to use others libraries in order to integrate the missing format, for example:

  • ajv-formats
  • ajv-openapi

I tryed also to override the instance of ajv used by Fastify with another one.

Steps to Reproduce

  1. Define a openApi specification that uses the float format for one of its properties;
  2. Create a Fastify app that uses the previous openApi specification to generate all its routes through the use of fastify-openapi-glue plugin;
  3. Inside the app code and before the use of fastify-openapi-glue register the fastify-response-validation plugin to enable the response validation;
  4. Run the app and see if the error occours.

Expected Behavior

Shouldn't throw the error reported in the description.

Response status code validation

Prerequisites

  • I have written a descriptive issue title
  • I have searched existing issues to ensure the issue has not already been raised

Issue

I wasn't sure if this is a bug or a feature, but I was wondering if it was possible to validate the response status code against the ones defined in the schema. Too many times I've found myself fixing the schema because the status codes defined there were not reflecting the ones returned by the endpoint's handler.

I've also created a PR for this: #98

randomUUID is not a function

Prerequisites

  • I have written a descriptive issue title
  • I have searched existing issues to ensure the issue has not already been raised

Issue

I am getting an error in fastify v4.17.0 of FastifyError [Error]: Failed building the serialization schema for POST: /bwb2-payments-1/bwb2-payments, due to error randomUUID is not a function

Support passing in a custom Ajv instance

Prerequisites

  • I have written a descriptive issue title
  • I have searched existing issues to ensure the feature has not already been requested

๐Ÿš€ Feature Proposal

Please provide the ability to pass in your own Ajv instance.

Motivation

Currently, one can only pass in ajv options, and the plugin instantiates ajv.
But to use latest drafts of JSON Schema, one has to import a different Ajv class than the default export: https://ajv.js.org/json-schema.html#draft-2020-12

In Fastify request validation, this is possible with setCompileFactory(), but it won't work for response validation.

Example

const ajv = new Ajv2020({ ... })
fastify.register(responseValidation, { ajv })

Cannot set ajv instace to 2019 and 2020

Prerequisites

  • I have written a descriptive issue title
  • I have searched existing issues to ensure the bug has not already been reported

Fastify version

4.26.1

Plugin version

2.5.1

Node.js version

21.7.1

Operating system

Linux

Operating system version (i.e. 20.04, 11.3, 10)

Docker node:latest

Description

Current plugin does not allow ajv instances created with non-draft 7 schemas to be used like:
ajv/dist/2019
ajv/dist/2020

Steps to Reproduce

import ajvNew from 'ajv/dist/2020.js';

export default fp(async (fastify) => {
  const ajv = new ajvNew.default();
  await fastify.register(response_validation, {
    ajv
  });
}


### Expected Behavior

Expect it to use my ajv instance internally. Right now the check for setting the ajv instance is:

if (opts.ajv && opts.ajv instanceof Ajv) {

However, this fails for this case since the ajv I am passing in is not of type Ajv.

Support shortcut schema syntax

๐Ÿš€ Feature Proposal

It is possible to drop wrapping object with type/properties keys and pass a properties directly (see 201 response schema):

image

https://www.fastify.io/docs/latest/Validation-and-Serialization/#serialization

Unfortunately fastify-response-validation won't pickup such syntax. onRoute is called before fastify will normalize schema definition therefore buildHook will be called with unexpected data: https://github.com/fastify/fastify-response-validation/blob/master/index.js#L22-L23

Example

test('Should support shortcut schema syntax', async t => {
  const fastify = Fastify()
  fastify.register(plugin)

  fastify.route({
    method: 'GET',
    path: '/',
    schema: {
      response: {
        '2xx': {
          answer: { type: 'number' }
        }
      }
    },
    handler: async (req, reply) => {
      return { answer: '42' }
    }
  })

  const response = await fastify.inject({
    method: 'GET',
    path: '/'
  })

  t.is(response.statusCode, 500)
  t.deepEqual(JSON.parse(response.payload), {
    statusCode: 500,
    error: 'Internal Server Error',
    message: 'response.answer should be number'
  })
})

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.