fastify / fastify-swagger

Swagger documentation generator for Fastify
MIT License
889 stars 199 forks source link

Support (responses) components with OpenAPI v3 #793

Open melroy89 opened 4 months ago

melroy89 commented 4 months ago

Prerequisites

Fastify version

4.26.2

Plugin version

8.14.0

Node.js version

20.11.1

Operating system

Linux

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

Linux Mint 23.1

Description

OpenAPI v3 support components, like component schemas, but also component responses. When trying to reference to OpenAPI components I get:

Uncaught:
FastifyError [FST_ERR_SCH_SERIALIZATION_BUILD]: Failed building the serialization schema for PUT: /some-route/:id, due to error Cannot find reference "#/components/responses/InternalServerError"

Supporting components section within fastify.register(fastifySwagger, { openapi: { .. here.... }}) would be very welcoming.

Steps to Reproduce

See below (this is valid syntax for OpenAPI v3 spec), this is how you can reproduce the problem:

const fastify = require('fastify')()

await fastify.register(require('@fastify/swagger'), {
  mode: 'dynamic',
  openapi: {
    openapi: '3.0.0',
    info: {
      title: 'Example',
      version: '0.3.0',
    },
    servers: [
      {
        url: 'http://localhost:{port}/{basePath}',
        description: 'Development server',
        variables: {
          port: {
            default: '3001'
          },
          basePath: {
            default: 'api/v1'
          }
        }
      }
    ],
    components: {
      responses: {
        InternalServerError: {
          description: 'Internal Server Error',
          content: {
            'application/json': {
              schema: {
                type: 'object',
                properties: {
                  message: {
                    type: 'string',
                    example: 'Unknown column \'field\' in \'where clause\'',
                  },
                },
              },
            },
          }
        }
      }
    }
  },
})

// Then use the components/responses in the schema
fastify.put('/some-route/:id', {
  schema: {
    description: 'post some data',
    tags: ['user', 'code'],
    summary: 'qwerty',
    security: [{ apiKey: [] }],
    params: {
      type: 'object',
      properties: {
        id: {
          type: 'string',
          description: 'user id'
        }
      }
    },
    body: {
      type: 'object',
      properties: {
        hello: { type: 'string' },
        obj: {
          type: 'object',
          properties: {
            some: { type: 'string' }
          }
        }
      }
    },
    response: {
      201: {
        description: 'Successful response',
        type: 'object',
        properties: {
          hello: { type: 'string' }
        }
      },
      500: {
        $ref: '#/components/responses/InternalServerError',
      },
    }
  }
}, (req, reply) => { })

await fastify.ready()
fastify.swagger()

Expected Behavior

That I can use OpenAPI components (incl. responses).

mcollina commented 4 months ago

Thanks for reporting! Would you like to send a Pull Request to address this issue? Remember to add unit tests.

melroy89 commented 4 months ago

I understand your response. I want to finish my migration towards Fastify to be honest (I'm now in a not working state basically). Frankly, I'm facing quite a lot of issues with OpenAPI schemas with Fastify implementation.

No offense, but as mentioned in the Discord help, I might use Zod together with zod-to-json-schema to workaround the missing features in Fastify Swagger. I'm trying to port over my app to Fastify, I was hoping it was a smooth migration.

mcollina commented 4 months ago

I’m pretty sure you are facing those issues because you are trying to port an application designed for one framework to another.

Last but not least: you are likely paid to do this work, and you are asking us to do it for you. Quite a few of us (either as individuals or via their employees) are willing to consult and help out. Saying “if you don’t help me I would use something else” would get you zero help here.

This is a volunteer driven, open-governed project.

melroy89 commented 4 months ago

I would like to share a reproduction GitHub repository which tries to use addSchema and definitions for reusing response objects in Fastify Swagger: https://github.com/melroy89/fastify-shared-definition-issue (as you notice this doesn't work either).

EDIT:

Even using the following (so NOT using definitions):

fastify.addSchema({
  $id: 'internalServerErrorResponse',
  type: 'object',       
  description: '500 Internal Server Error',
  properties: {
    message: {
      type: 'string',
      description: 'Error message',
      example: 'Some internal error message'
    }
  }
})

And using it like this:

schema: {
  description: 'Root example',
  response: {
   500: {
      $ref: 'internalServerErrorResponse#'
    }
}

The Swagger shows me the wrong response message (default response message? It says "Default Response"):

image

melroy89 commented 4 months ago

I’m pretty sure you are facing those issues because you are trying to port an application designed for one framework to another.

Last but not least: you are likely paid to do this work, and you are asking us to do it for you. Quite a few of us (either as individuals or via their employees) are willing to consult and help out. Saying “if you don’t help me I would use something else” would get you zero help here.

No. I created fastify from scratch. Using an empty fastify project. And adding plugins and everything from scratch.

And no, I'm not getting paid to do this work!! This is all free time for me.

It would be nice if you took these problems more seriously.

Saying “if you don’t help me I would use something else” would get you zero help here.

Somebody on Discord mentioned similar issues, and told me to try Zod.

I understand it's a community driven my volunteers. I'm also a volunteer. I already tried to help this project already with PRs. I don't like your attitude at all. Sorry.

mcollina commented 4 months ago

If I didn’t take the bug seriously, I would have told you this wasn’t a bug. It’s just not a bug I’m facing, and right now I have no time to dedicate to this. I receive roughly 100-150 notifications a day from the various repos I maintain. If everyone started pinging for attention in chats & issues for help, I would burn out very quickly (and I did in the past). Specifically saying “I would need to use something else if you don't help me” is a blackmail game that I would not play, and it’s a game that does not sit well in this community.

melroy89 commented 4 months ago

I didn't ping you in this issue ticket?

melroy89 commented 3 months ago

I would like to share a reproduction GitHub repository which tries to use addSchema and definitions for reusing response objects in Fastify Swagger: https://github.com/melroy89/fastify-shared-definition-issue (as you notice this doesn't work either).

EDIT:

Even using the following (so NOT using definitions):

fastify.addSchema({
  $id: 'internalServerErrorResponse',
  type: 'object',       
  description: '500 Internal Server Error',
  properties: {
    message: {
      type: 'string',
      description: 'Error message',
      example: 'Some internal error message'
    }
  }
})

And using it like this:

schema: {
  description: 'Root example',
  response: {
   500: {
      $ref: 'internalServerErrorResponse#'
    }
}

The Swagger shows me the wrong response message (default response message? It says "Default Response"):

image

I move this issue to a separate issue: https://github.com/fastify/fastify-swagger/issues/795