seriousme / fastify-openapi-glue

A plugin for the Fastify webserver to autogenerate a Fastify configuration based on a OpenApi(v2/v3) specification.
MIT License
206 stars 33 forks source link

Validation Errors when embedding $refs to models that contain "x-" or "example" keywords #463

Closed glennsc closed 1 year ago

glennsc commented 1 year ago

I build out an OpenAPI spec in Stoplight Studio, export the bundled ref to a .yaml file and use that in my fastify app as the spec for fastify-openapi-glue.. It worked until I started embedding $refs to models, and now I get validation errors for specific keywords in the model, such as:

FastifyError [Error]: Failed building the validation schema for POST: /parties/:partyId/addresses, due to error strict mode: unknown keyword: "example"

If I extract just the relevant POST from that spec:

    post:
      summary: Create a new address for a party
      operationId: postPartiesIdAddresses
      responses:
        '200':
          $ref: '#/components/responses/Address'
      description: Create a new address for a party
      tags:
        - Address
        - Party
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AddressRequest'

... no examples here, but you will see there are to $refs: one to an Address response and one to an AddressRequest request body.

In the response schema, there is a reference to an Address model. That model has many examples in it. An excerpt:

country:
  type: string
  example: US
  maxLength: 2
  description: |-
    The two-letter ISO 3166-1 alpha-2 country code

    See: https://en.wikipedia.org/wiki/ISO_3166-2

If I remove the examples such as the one above the schema validates.

Debugging this has been a little difficult for me. I can't tell if the problem is in Fastify, fastify-openapi-glue, Ajv, or perhaps Stoplight is bundling the references incorrectly? Is it when $refs are layered two levels deep?

I should point out that the example keyword won't validate when embedded in a ref, nor will any keyword that starts with "x-" such as x-stoplight or x-tags.

The full error:

FastifyError [Error]: Failed building the validation schema for POST: /parties/:partyId/addresses, due to error strict mode: unknown keyword: "example"
  at Boot.<anonymous> (node_modules/.pnpm/fastify@4.15.0/node_modules/fastify/lib/route.js:366:21)
  at Object.onceWrapper (node:events:627:28)
  at Boot.emit (node:events:525:35)
  at node_modules/.pnpm/avvio@8.2.1/node_modules/avvio/boot.js:160:12
  at node_modules/.pnpm/avvio@8.2.1/node_modules/avvio/plugin.js:275:7
  at done (node_modules/.pnpm/avvio@8.2.1/node_modules/avvio/plugin.js:200:5)
  at check (node_modules/.pnpm/avvio@8.2.1/node_modules/avvio/plugin.js:224:9)
  at node:internal/process/task_queues:140:7
  at AsyncResource.runInAsyncScope (node:async_hooks:204:9)
  at AsyncResource.runMicrotask (node:internal/process/task_queues:137:8) {
 code: 'FST_ERR_SCH_VALIDATION_BUILD',
 statusCode: 500
seriousme commented 1 year ago

Hi,

thanks for asking.

It's a bit hard to draw conclusions based on what is written above. The error itself is a typical fastify error, not fastify-openapi-glue .

I think its caused by fastify's setting of strict mode as a default parameter to AJV.

I ran into a similar issue with the PetStore example.

The solution there was to add an explicit option to fastify:

https://github.com/seriousme/fastify-openapi-glue/blob/33bb43c2bc36bd6fec542df10f532bb02b138110/examples/petstore/index.js#L19-L25

Hope this helps!

Kind regards, Hans

seriousme commented 1 year ago

ps. you can also add such flags directly to fastify on startup: https://www.fastify.io/docs/latest/Reference/Server/#factory-ajv

glennsc commented 1 year ago

Thank you so much for the fast response. Indeed, turning that ajv strict mode off worked. Deeply appreciated.