SkeLLLa/fastify-oas

Multiple types not supported

Closed this issue · 4 comments

Awesome library! I have completely autogenerated docs thanks to this repo 💪

One thing I believe I have stumbled across is that you can't have multiple types e.g:

Note: SwaggerHelper.modelToSwaggerProps is just a method that maps Sequelize model datatypes to Swagger datatypes

const {ProjectUsers, Projects} = require('my-sequelize-model-repo')

fastify.addSchema({
  $id: 'projectUser',
  type: 'object',
  properties: Object.assign(
    SwaggerHelper.modelToSwaggerProps(ProjectUsers, true)[ProjectUser],
    {
      Project: {
        type: ['object', 'null'],
        nullable: true,
        properties: SwaggerHelper.modelToSwaggerProps(Projects)[Project]
      }
    }
  )
})

Which will generate...

{
 '$id': 'projectUser',
  type: 'object',
  properties: {
     id: { type: 'integer' },
     user_id: { type: 'integer' },
     project_id: { type: 'integer' },
     notes: { type: 'string' },
     occurred_at: { type: 'string', format: 'date-time' },
     created_at: { type: 'string', format: 'date-time' },
     updated_at: { type: 'string', format: 'date-time' },
     deleted_at: { type: 'string', format: 'date-time' },
     Project: {
         type: ['object', 'null'],
         nullable: true,
         properties: {
            id: { type: 'integer' },
            name: { type: 'string' }
         }
     }
  }
}

Note the attempt to get the child association (Project) to be either an object or null

I think this was also caught in another implementation: AfterShip/swagger-ajv#19

This has got me in quite the pickle because Ajv (the default json validator with fastify) isn't happy with if the Project model is null if I just keep the type as 'object'. This configuration works in the API response through Ajv - but it breaks in swagger docs

image

image

@bneigher have you tried use oneOf or anyOf instead multiple types?

Project: {
  oneOf: [{
    type: object,
    properties: { ... }
  }, {
    type: null
  }],
}

Also as far as I know types as array are not valid in swagger as well. See docs

I have - @SkeLLLa. I think the issue with this ends up being that Ajv doesn't work with this format. So effectively the solution to the problem is either adding the ability to convert types [] to oneOf for the OAS generation, or else the solution needs to be dealt with on the Ajv side which there is discussion about it not choosing to be implemented.

Will dig deeper - but AFAIK doing such a thing which is expected for swagger is not supported with Fastify due to the tight coupling of Ajv with fastify be default

Converting of types array to oneOf is possible, however it will be not effective unless ajv and fastify will enable support of such schemes, just as you said. So even if OAS plugin will have such conversion, fastify will not work with such route.

Also IMHO oneOf and anyOf completely cover all goals that types[] have and even more. As those types[] not supported neither in Fastify, nor in OpenApi, so there's no reason to support such thing in this plugin until at least one of ajv or Fastify will add support of this.

Closing this for now, cause neither ajv/fastify, nor swagger/openapi supports such type declaration.