fastify-swagger: Swagger Docs generated do not show added schemas as models

Feature Request

While fastify-swagger is great for schemas attached to routes, I also would expect to be able to leverage it for displaying the models independent of the routes (usually shown at the bottom of the generated swagger-ui). When I call fastify.addSchema on one of my reusable schemas, I would expect it to show up as a model.

To Reproduce

Steps to reproduce the behavior:

  1. generate a boilerplate fastify app with fastify-cli

Paste your code here: 2. change the app.js file to the following (basically copy / pasted from fastify-swagger + my example of trying to use the schema to display a model

"use strict";

const path = require("path");
const AutoLoad = require("fastify-autoload");

module.exports = function(fastify, opts, next) {
  // Place here your custom code!

  // Do not touch the following lines

  // This loads all plugins defined in plugins
  // those should be support plugins that are reused
  // through your application
  fastify.register(AutoLoad, {
    dir: path.join(__dirname, "plugins"),
    options: Object.assign({}, opts)
  });

  // This loads all plugins defined in services
  // define your routes in one of these
  fastify.register(AutoLoad, {
    dir: path.join(__dirname, "services"),
    options: Object.assign({}, opts)
  });

  fastify.register(require("fastify-swagger"), {
    routePrefix: "/documentation",
    swagger: {
      info: {
        title: "Test swagger",
        description: "testing the fastify swagger api",
        version: "0.1.0"
      },
      externalDocs: {
        url: "https://swagger.io",
        description: "Find more info here"
      },
      host: "localhost",
      schemes: ["http"],
      consumes: ["application/json"],
      produces: ["application/json"],
      tags: [
        { name: "user", description: "User related end-points" },
        { name: "code", description: "Code related end-points" }
      ],
      securityDefinitions: {
        apiKey: {
          type: "apiKey",
          name: "apiKey",
          in: "header"
        }
      }
    },
    exposeRoute: true
  });

  const schemaIWantToAdd = {
    $id: "User",
    type: "object",
    required: ["id", "firstName", "lastName", "email"],
    properties: {
      id: { type: "string", format: "uuid" },
      firstName: { type: "string" },
      lastName: { type: "string" },
      email: { type: "string", format: "email" }
    }
  };

  // trying to use the schema as a model below
  fastify.addSchema(schemaIWantToAdd);

  fastify.ready(err => {
    if (err) throw err;
    fastify.swagger();
  });

  fastify.get(
    "/some-route",
    {
      schema: {
        description: "post some data",
        tags: ["user", "code"],
        summary: "qwerty",
        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" }
            }
          }
        },
        security: [
          {
            apiKey: []
          }
        ]
      }
    },
    async (req, reply) => {
      return { hello: "world" };
    }
  );

  // Make sure to call next when done
  next();
};

Expected behavior

I would expect the added schema would show up as a model at the bottom of the generated swagger-ui

Paste the results here:

image

Your Environment

  • node version: 12
  • fastify version: >=2.0.0
  • os: Mac

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Comments: 17 (11 by maintainers)

Most upvoted comments

I am having huge problems referencing a model saved in definitions.

definitions: {
    user: {
        type: 'object',
        properties: {
            surname: {type: 'string'},
            lastname: {type: 'string'},
            birthday: {type: 'string', format: 'date'},
            email: {type: 'string'},
            street: {type: 'string'},
            city: {type: 'string'},
            zip: {type: 'number'},
            phone: {type: 'string'},
            mobile: {type: 'string'},
            password: {type: 'string'}
        }
    }
}

How do I reference this model from my route?

$ref: '#/definitions/user' is giving me following error

‘Failed building the validation schema for POST: /users, due to error can't resolve reference #/definitions/user from id #’

Setting definitions in swagger options works for simple schemas but when you have $refs in the schema they seem to get replaced inline with what the $ref was referring to. So you get duplicated type definitions nested within a parent (in addition to a top level type). This is reflected in the models in swagger UI. Also this is bad if you generate types from the swagger spec.

@brandondoran I’ve been tripped up by this behavior as well. Did you manage to find a solution?

Setting definitions in swagger options works for simple schemas but when you have $refs in the schema they seem to get replaced inline with what the $ref was referring to. So you get duplicated type definitions nested within a parent (in addition to a top level type). This is reflected in the models in swagger UI. Also this is bad if you generate types from the swagger spec.