feathers-swagger: Attached model schema not available in app.js using crow generated service

What did I do?

  1. running feathers v4
  2. app with multiple fully functioning swagger model-schemas (services generated using feathers v3)
  3. generated a new service using feather v4
  4. added a model schema to service.model for that new service
  5. confirmed the model schema is generated and attached to the service (in the service file)

What happens?

I checked the Swagger UI and not model schema for the newly generated service. Looking further it appears service.model is not available/undefined in app.js whereas it is for all other services that were generated using the feathers v3 cli.

as a workaround I keep using the v3 service style for now.

app.js

The console.log message below indicates the exact point where things go amiss, undefined for the v4 service. Interesting: the console.debug at the very bottom does show the model schema so I am sure it is added.

app.js

// Configure other middleware (see `middleware/index.js`)
app.configure(middleware);
app.configure(authentication);

// Set up swagger (OpenAPI)
app.configure(
  swagger({
    openApiVersion: 3,
    uiIndex: true,
    docsPath: '/docs',
    docsJsonPath: '/docs/schema',
    specs: {
      info: {
        title: 'P2 API',
        description: 'A description',
        version: '0.0.1',
      },
    },
    defaults: {
      schemasGenerator(service, model, modelName) {
        if (model === 'projects') {
          console.log(service.model); // not set for the v4 service
        }

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

// Set up our services (see `services/index.js`)
app.configure(services);

console.log('------------------------');
console.log(app.service('projects').model);

Services

v3 generated projects service (working)

service.model set here is available in app.js for use by the SchemaGenerator.

// Initializes the `projects` service on path `/projects`
const createService = require('feathers-sequelize');
const createModel = require('../../models/projects.model');
const hooks = require('./projects.hooks');

module.exports = function init(app) {
  const Model = createModel(app);
  const paginate = app.get('paginate');

  const options = {
    Model,
    paginate,
  };

  // create service
  const service = createService(options);

  // generate OpenAPI 3.0 model schema as required by feathers-swagger
  service.model = app
    .get('jsonSchemaManager')
    .generate(Model, app.get('openApi3Strategy'));

  // get initialized service so we can register hooks
  app.use('/projects', service);

  // register hooks
  app.service('projects').hooks(hooks);
};

v4 generated projects service (not working)

service.model set here is NOT available in app.js for use by the SchemaGenerator.

// Initializes the `projects` service on path `/projects`
const { Projects } = require('./projects.class');
const createModel = require('../../models/projects.model');
const hooks = require('./projects.hooks');

module.exports = function (app) {
  const Model = createModel(app);
  const paginate = app.get('paginate');

  const options = {
    Model,
    paginate
  };

  // Initialize our service with any options it requires
  app.use('/projects', new Projects(options, app));

  // Get our initialized service so that we can register hooks
  const service = app.service('projects');

  // generate OpenAPI 3.0 model schema as required by feathers-swagger
  service.model = app
    .get('jsonSchemaManager')
    .generate(Model, app.get('openApi3Strategy'));

  service.hooks(hooks);
};

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Comments: 25 (12 by maintainers)

Most upvoted comments

Never used mongoose

Yes it was theoretically for sequelize, I just tested it with with NeDB, there it was working.

Well there could also be services that are not sequelize services, so I would add a check for that.

const { Service: SequelizeService } = require('feathers-sequelize');

// ...
schemasGenerator(service, model, modelName) {
  if (!service instanceof SequelizeService) {
    return {};
  }

  //...
}

Ok sorry, I wrote stupid things, not the app.configure but the app.use is the call that triggers the mixins that are used by the feathers-swagger package.

In the service, you used for feathers version 4 you have

 // Initialize our service with any options it requires
  app.use('/projects', new Projects(options, app));

  // Get our initialized service so that we can register hooks
  const service = app.service('projects');

  // generate OpenAPI 3.0 model schema as required by feathers-swagger
  service.model = app
    .get('jsonSchemaManager')
    .generate(Model, app.get('openApi3Strategy'));

There you fetch the initialized service from feathers, but this is different from the service that will be used when registering a service. Properties you want to use in feathers-sagger have to be set before calling app.use.

 const service = new Projects(options, app);

  // generate OpenAPI 3.0 model schema as required by feathers-swagger
  service.model = app
    .get('jsonSchemaManager')
    .generate(Model, app.get('openApi3Strategy'));

 // Initialize our service with any options it requires
  app.use('/projects', service);

Should do the trick. You can also do the service.model = … stuff in the constructor of the Projects class.