Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dynamic model discovery: "Swagger: skipping unknown type" error - no schema defined in Swagger UI #3726

Closed
twboc opened this issue Dec 9, 2017 · 2 comments

Comments

@twboc
Copy link

twboc commented Dec 9, 2017

Swagger cannot process dynamically discovered models on boot time which ends in a situation that Model schema is undefined in the swagger UI.

Swagger: skipping unknown type 'ModelType'

PACKAGE:

{
"compression": "^1.0.3",
"cors": "^2.5.2",
"helmet": "^1.3.0",
"loopback": "^3.17.0",
"loopback-boot": "^3.1.0",
"loopback-swagger" : "^5.5.0",
"loopback-component-explorer": "^5.2.0",
"serve-favicon": "^2.0.1",
"strong-error-handler": "^2.0.0"
}

CODE:

'use strict';

var loopback = require('loopback');
var boot = require('loopback-boot');

var app = module.exports = loopback({localRegistry: true});

var ds = loopback.createDataSource('postgresql', {
  "host": "localhost",
  "port": 5432,
  "database": "db",
  "username": "user",
  "password": "pass"
});

var acceptedTables = [
  'users',
  'organisation',
  'expectation',
  'location',
  'tags',
  'telephone',
  'email',
  'experience',
  'project',
  'skill',
  'education',
  'language',
  'activity',
  'hobby',
  'social',
  'link',
  'document',
  'user_organisation',
  'users_data',
  'document_permissions',
  'tag_relations'
]

var modelDefinitionsConf = {views: true};
var modelConfig = { schema: 'public' };

function capitalizeFirstLetter(string) {
    return string.charAt(0).toUpperCase() + string.slice(1);
}

function generateModelName(modelName){
  var nameArr = modelName.split(/_|-/);
  var nameArr = nameArr.map(function(el){ return el[0].toUpperCase() + el.substr(1); });
  return nameArr.join('');
}

app.start = function() {
  return app.listen(function() {
    app.emit('started');
    var baseUrl = app.get('url').replace(/\/$/, '');
    ds.discoverModelDefinitions(modelDefinitionsConf, function(err, data){
      for (var el in data) {
        (function(modelName){
          if (acceptedTables.indexOf(modelName) >= 0) {
              ds.discoverSchema(modelName, function (err, schema) {
                var model = ds.createModel(schema.name, schema.properties, schema.options);
                app.model(model, {public : true, dataSource: ds });
              })
          }
        })(data[el].name)
      }
    });
    if (app.get('loopback-component-explorer')) {
      var explorerPath = app.get('loopback-component-explorer').mountPath;
      console.log('Browse your REST API at %s%s', baseUrl, explorerPath);
    }
  });
};

// Bootstrap the application, configure models, datasources and middleware.
// Sub-apps like REST API are mounted via boot scripts.
boot(app, __dirname, function(err) {
  if (err) throw err;

  // start the server if `$ node server.js`
  if (require.main === module)
    app.start();
});
@jannyHou
Copy link
Contributor

jannyHou commented Dec 11, 2017

@twboc Unfortunately in LoopBack3 you could not load the dynamically built model in swagger, this is limited by the boot module: swagger is one of the built-in plugins that get executed before any boot script files, and also before function app.start, as you can see from the code

boot(app, __dirname, function(err) {
  if (err) throw err;

  // start the server if `$ node server.js`
  if (require.main === module)
    app.start();
});

Now the team is working on a new version of LoopBack, and the boot implementation is about to start, please see story:
loopbackio/loopback-next#441

We appreciate your suggested feature and will see if we can make it happen in the next version of the boot module!

I am closing the issue here, we can keep discussion of possibility in loopbackio/loopback-next#441, feel free to reopen it if you have other questions, thanks for understanding.

@prateek-raj
Copy link

prateek-raj commented Jun 12, 2021

I got a solution by defining the custom model in model-config with options

"custom_model": {
 "dataSource": null,
"public": false
}

Hope this might help. This worked for me :P

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants