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

Feature/#46 mongoose model definitions #61

Merged

Conversation

maxiejbe
Copy link
Contributor

Changes to include mongoose model as spec definitions (Issue #45):

  • Init argument: mongooseModels?: Array<string>
  • Dependency mongoose-to-swagger to convert mongoose models to definitions (spec).
  • Dev dependencies: mongoose + bson.
  • README.md + Tests.

lib/mongoose.js Outdated
/* Disabling because its a peer dependency */
/* eslint-disable global-require */
/* @ts-ignore */
const mongoose = require('mongoose');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you could require the mongoose package at the top-level scope, just like you've done with m2s. This will be more efficient since you won't have to re-require the mongoose package every time the function is called (it will instead only be required once - when the file loads).

Copy link
Contributor Author

@maxiejbe maxiejbe Jul 25, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a good one 😄 It was intentional. We could include the mongoose package as a:

a) Peer dependency.
This was the original idea. The installation is optional for the client (could be using Sequelize for example).
As we can't handle errors at top-level scope, it would throw in case we require an uninstalled package.
Even though it's less performant to re-require inside the generateMongooseModelsSpec scope, that function is intended to be called once and then use the same generated spec every time.

Ignore that it's also included as a Dev dependency, that was for basic_server.js testing purposes.

b) Regular dependency.
The installation would be required (even if not needed by the client).
It could also lead to issues if the mongoose package version from the client is different from the one used as a dependency on express-oas-generator.
In this case, top-level scope require would be correct.

For both cases, we should decide which is the minimum required version: https://mongoosejs.com/docs/compatibility.html

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't const m2s = require('mongoose-to-swagger'); be moved inside generateMongooseModelsSpec as well to have it as peer dependency?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't const m2s = require('mongoose-to-swagger'); be moved inside generateMongooseModelsSpec as well to have it as peer dependency?

Sure, so should be go in both cases (mongoose, mongoose-to-swagger) with peer dependencies?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They are all now peer dependencies (bson, mongoose, mongoose-to-swagger). We should now agree the minimum required versions.

@@ -320,7 +325,7 @@ function handleRequests() {
/**
* @type { typeof import('./index').init }
*/
function init(aApp, aPredefinedSpec = {}, aSpecOutputPath = undefined, aWriteInterval = 1000 * 10, aSwaggerUiServePath = 'api-docs') {
function init(aApp, aPredefinedSpec = {}, aSpecOutputPath = undefined, aWriteInterval = 1000 * 10, aSwaggerUiServePath = 'api-docs', mongooseModels = []) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you also include this functionality in the handleResponses function? The init one is only for backwards-compatibility and basic usage only; everything else uses handleResponses and handleRequests.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done! I've also updated both server_basic.js and server_advanced.js examples.

@kiprasmel
Copy link
Contributor

Thank you for your contribution! I haven't tried it our yet, but it looks promising:)

lib/mongoose.js Outdated
/* Disabling because its a peer dependency */
/* eslint-disable global-require */
/* @ts-ignore */
const mongoose = require('mongoose');
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't const m2s = require('mongoose-to-swagger'); be moved inside generateMongooseModelsSpec as well to have it as peer dependency?

const mongooseModels = ['User', 'Student'];

try {
generateMongooseModelsSpec(mongooseModels);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

using expect().to.throw(Error) makes code more readable

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done, now using expect().toThrowError(new RegExp())

lib/mongoose.js Outdated


} catch (err) {
throw new Error(`${err.message}`);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like here any thrown exception is overwritten and rethrown, why is it needed? Would it be better to delete try/catch and allow original error to be thrown to simplify debugging?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I was wrapping with an extended error message before. Just removed it.

index.js Outdated
if (validMongooseModels && !mongooseModelsSpecs) {
mongooseModelsSpecs = generateMongooseModelsSpec(mongooseModels);
}
return mongooseModelsSpecs;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there any place where value returned from that functino is used? Maybe that return is not needed?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nope, it wasn't used. Returning void right now.

@mpashkovskiy mpashkovskiy merged commit a975734 into mpashkovskiy:master Jul 29, 2020
@mpashkovskiy
Copy link
Owner

@maxiejbe thanks for your contribution! I'll test it locally and publish a new version soon. Will add a comment here after.

@mpashkovskiy
Copy link
Owner

version 1.0.25 is published, @maxiejbe could you please try it and confirm that it works as expected?

@maxiejbe
Copy link
Contributor Author

Just tried an example project and working as expected!

If mongooseModels argument is not supplied, working as previous versions.

Sending the argument to handleResponses:

expressOasGenerator.handleResponses(server, {
    predefinedSpec(spec) {
      return spec;
    },
    specOutputPath: swaggerDocumentPath,
    mongooseModels: mongoose.modelNames(),
});

First asking for the dependencies:
Error: Cannot find module 'mongoose-to-swagger'.

Then generating the model docs:
image

@maxiejbe
Copy link
Contributor Author

A few comments only (but not related, it's up to mongoose-to-swagger package):

  • Not removing non-public mongoose schema fields
  • Not detecting Schema.Types.ObjectId (ref to another model).

@mpashkovskiy
Copy link
Owner

First asking for the dependencies:
Error: Cannot find module 'mongoose-to-swagger'.

Should it be added to README.md? Something like If you are using mongooseModels parameter don't forget install mongoose-to-swagger module?

@maxiejbe
Copy link
Contributor Author

First asking for the dependencies:
Error: Cannot find module 'mongoose-to-swagger'.

Should it be added to README.md? Something like If you are using mongooseModels parameter don't forget install mongoose-to-swagger module?

Already done:
['User','Student'] - Mongoose models to be included as definitions. To get all just do mongoose.modelNames(). The following peer dependencies are required to use this last argument: mongoose, mongoose-to-swagger, bson.

@maxiejbe maxiejbe deleted the feature/#46-mongoose-model-definitions branch September 9, 2020 14:13
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

Successfully merging this pull request may close these issues.

None yet

3 participants