feathersjs-ecosystem / feathers-swagger

Add documentation to your FeatherJS services and feed them to Swagger UI.
MIT License
226 stars 63 forks source link

Swagger sequelize schema generation #263

Closed pratikdevdas closed 1 month ago

pratikdevdas commented 1 month ago

My end goal is to attach schema to my autogenerated swagger route definitions. When I call my swagger middleware before services, I get the route, but my schema is ignored. And when I call my swagger middleware after the services, it says nothing is defined in the specs. According to the docs, I am aware that the swagger initialization should always be done before the services.

The following code generates the schema only when the swagger is defined after services:

import { Model } from'sequelize''
import { JsonSchemaManager, OpenApi3Strategy } from '@alt3/sequelize-to-json-schemas'
import swagger from 'feathers-swagger'
import { Application } from '../../types/declarations'
// import {SCHEMA} from './constants'

export function generateModelSchemas(sequelize: any) {
    const schemaManager = new JsonSchemaManager()
    // console.log(sequelize.modelManager.models)
    const schemas: { [key: string]: object } = {}
    sequelize.modelManager.models.forEach((model: typeof Model) => {
        const schema = schemaManager.generate(model, new OpenApi3Strategy())
        schemas[model.name] = schema
    })
    return schemas
}

export default (app: Application) => {
    const sequelize = app.get('sequelize');
    const schemas = generateModelSchemas(sequelize);

    app.configure(   swagger({
        specs: {
          info: {
            title: 'A test',
            description: 'A description',
            version: '1.0.0',
          },
          components: {
            schemas: Object.keys(schemas).length > 0 ? schemas : {}, 
          },
        },
        ui: swagger.swaggerUI({
          docsPath: '/docs-test',
        }),
      }));
  };

usage: app.configure(services) app.configure(swagger)

Mairu commented 1 month ago

Hi @pratikdevdas, have you found a solution yourself?

pratikdevdas commented 1 month ago

Yes one could do it modifying there code like this typically using schema generator.

  defaults: {
            schemasGenerator(service, model, modelName, schemas) {
              if (service.options && service.options.Model) {
                const modelSchema = app
                  .get('jsonSchemaManager')
                  .generate(
                    service.options.Model,
                    app.get('openApi3Strategy'),
                    service.options.Model.options.jsonSchema
                  );

                return {
                  [model]: modelSchema,
                  [`${model}_pagination`]: {
                    title: `${modelName} pagination`,
                    type: 'array',
                    items: { $ref: `#/components/schemas/${model}` },
                  },
                  [`${model}_list`]: {
                    title: `${modelName} list`,
                    type: 'array',
                    items: { $ref: `#/components/schemas/${model}` },
                  },
                };
              }
              return {};
            },

          },