restivus-swagger icon indicating copy to clipboard operation
restivus-swagger copied to clipboard

Allow Restivus to output Users related endpoint when outputting swagger document

Open matleppa opened this issue 7 years ago • 15 comments

When REST API is generating swagger document of endpoints from API data, it is needed to generate the users collection related endpoints too. At the moment Restivus generates other endpoints, but not the ones, which are related to users. There is a restiction in Restivus code. It looks for string 'users' and in case it it found in path string, it is skipped.

matleppa avatar Jun 07 '17 08:06 matleppa

You can skip any route you want by adding the param to hide: https://github.com/apinf/restivus-swagger#hidden-routes

dcantatore avatar Jun 07 '17 15:06 dcantatore

Actually, what is needed, is the other way around. At the moment the routes related to 'users' are skipped by restivus-swagger, but in certain API also those routes are needed to be visible.

matleppa avatar Jun 08 '17 08:06 matleppa

What routes are skipped? Do you mean the login and logout routes?

dcantatore avatar Jun 08 '17 13:06 dcantatore

Hi,

I mean the routes with string 'users' in path.

// Loop through all routes let paths = {}; _ . each ( restivus . _routes , function ( route ) { // Exclude swagger, login, logout, users paths, and routes with option hidden set to any truthy value if ( route . path !== swaggerPath && route . path !== ' login ' && route . path !== ' logout ' && ! route . options . hidden && ! route . path . includes ( ' users ' ) ) { // Modify path parameter to swagger spec style

matleppa avatar Jun 08 '17 13:06 matleppa

I know you mean the routes with users in the path, but I don't know what default routes that are blocked that you are referring to. Can you show me an example?

dcantatore avatar Jun 08 '17 13:06 dcantatore

OK,

There is an API, in which there are functionality for following routes:

ApiV1.addRoute('organizations', { ApiV1.addRoute('organizations/:id', {

ApiV1.addCollection(Apis, {

ApiV1.addCollection(Meteor.users, { ApiV1.addRoute('users/updates', {

When a swagger file is generated: // Generate Swagger to route /rest/v1/swagger.json ApiV1.addSwagger('swagger.json'); export default ApiV1;

The swagger file is containing following paths: "/apis": { "/apis/{id}": { "/organizations": {

"/organizations/{id}": { But there are no paths related to users. So it seems clear to me, that they are missing because of the condition ... ! route . path . includes ( ' users ' ) ... in restivus-swagger.

What do you think, is there another way -- than removing the condition -- to get all the routes included in generated swagger document?

matleppa avatar Jun 08 '17 14:06 matleppa

You can define your own paths by using this: https://github.com/apinf/restivus-swagger#define-paths-outside-of-routes

Have you tried that?

The problem is making sense to me now, I think users is excluded by default for safety. I didn't write that line to exclude them but I can imagine that's why.

I also saw this in the restivus docs: https://github.com/kahmali/meteor-restivus/#collection

'...The Meteor.users collection will have [special endpoints] (#users-collection-endpoints) generated....'

dcantatore avatar Jun 08 '17 14:06 dcantatore

The functionality mentioned in first link seems not to work, no change in generated swagger document. No effect regardless the change of path name given (not containing 'users').

I guess the latter one is about functionality, not about generating swagger document.

matleppa avatar Jun 09 '17 10:06 matleppa

Adding paths manually definitely works, I am currently using it. Can you paste the code where you tried to use it?

dcantatore avatar Jun 09 '17 10:06 dcantatore

Here is the main module.

What I added for testing is the paths-section with test path 'mulkoturpa'.In generated document other paths come from different files.

But this 'mulkoturpa' path is not in generated document.


/* Copyright 2017 Apinf Oy This file is covered by the EUPL license. You may obtain a copy of the licence at https://joinup.ec.europa.eu/community/eupl/og_page/european-union-public-licence-eupl-v11 */ // Meteor contributed packages imports import { Restivus } from 'meteor/nimble:restivus'; const ApiV1 = new Restivus({ apiPath: 'rest', version: 'v1', defaultHeaders: { 'Content-Type': 'application/json', }, useDefaultAuth: true, prettyJson: true, enableCors: true, }); // Add Restivus Swagger configuration - meta, tags, params, definitions ApiV1.swagger = { paths: { '/mulkoturpa': { get: { description: 'Returns user with given ID.', parameters: { name: 'id', in: 'path', description: 'ID of User', required: true, type: 'string', }, responses: { 200: { description: 'One user.', }, }, }, }, }, meta: { swagger: '2.0', info: { description: 'APinf is open source API management and catalog. ', version: '1.0.0', title: 'Admin API', }, securityDefinitions: { userSecurityToken: { in: 'header', name: 'X-Auth-Token', type: 'apiKey', }, userId: { in: 'header', name: 'X-User-Id', type: 'apiKey', }, }, },

tags: { api: 'APIs', organization: 'Organizations', users: 'Users', }, params: { api: { name: 'api', in: 'body', description: 'Data for adding or editing API', schema: { $ref: '#/definitions/api', }, }, apiId: { name: 'id', in: 'path', description: 'ID of API', required: true, type: 'string', }, company: { name: 'company', in: 'body', description: 'Company name of user', required: true, type: 'string', }, email: { name: 'email', in: 'body', description: 'Email address for user', required: true, type: 'string', }, lifecycle: { name: 'lifecycle', in: 'query', description: 'Limit the listing based on lifecycle status of APIs.', required: false, type: 'string', enum: ['design', 'development', 'testing', 'production', 'deprecated'], }, limit: { name: 'limit', in: 'query', description: 'Maximum number of records to return in query.', required: false, type: 'integer', format: 'int32', minimum: 0, maximum: 50, }, optionalSearch: { name: 'q', in: 'query', description: 'An optional search string for looking up inventory.', required: false, type: 'string', }, organization: { name: 'organization', in: 'body', description: 'Data for adding or editing Organization', schema: { $ref: '#/definitions/organization', }, }, organizationApi: { name: 'organization', in: 'query', description: 'An optional organization id will limit results to the given organization.', required: false, type: 'string', }, organizationId: { name: 'id', in: 'path', description: 'ID of Organization', required: true, type: 'string', }, password: { name: 'password', in: 'body', description: 'Password for user', required: true, type: 'string', }, since: { name: 'since', in: 'path', description: 'Time frame in days', required: true, type: 'integer', format: 'int32', minimum: 1, }, userId: { name: 'id', in: 'path', description: 'ID of User', required: true, type: 'string', }, userName: { name: 'username', in: 'body', description: 'Username', required: true, type: 'string', }, skip: { name: 'skip', in: 'query', description: 'Number of records to skip for pagination.', required: false, type: 'integer', format: 'int32', minimum: 0, }, },

definitions: { // The schema defining the type used for the body parameter. api: { required: ['name', 'url'], properties: { name: { type: 'string', example: 'My REST API', }, description: { type: 'string', example: 'My REST API description', }, url: { type: 'string', format: 'url', example: 'https://my.rest.api.com/v1', }, lifecycleStatus: { type: 'string', enum: ['design', 'development', 'testing', 'production', 'deprecated'], }, }, }, organization: { required: ['name', 'url'], properties: { name: { type: 'string', example: 'Company', }, description: { type: 'string', example: 'Description about company', }, url: { type: 'string', format: 'url', example: 'https://organization.com', }, contact_name: { type: 'string', description: 'Name of company manager', example: 'David Bar', }, contact_phone: { type: 'string', description: 'Phone number of company manager', example: '+7 000 000 00 00', }, contact_email: { type: 'string', format: 'email', description: 'E-mail address of company manager', example: '[email protected]', }, facebook: { type: 'string', format: 'url', description: 'Link to Facebook', example: 'http://url.com', }, twitter: { type: 'string', format: 'url', description: 'Link to Twitter', example: 'http://url.com', }, instagram: { type: 'string', format: 'url', description: 'Link to Instagram', example: 'http://url.com', }, linkedin: { type: 'string', format: 'url', description: 'Link to Linked In', example: 'http://url.com', }, }, }, }, }; // Generate Swagger to route /rest/v1/swagger.json ApiV1.addSwagger('swagger.json'); export default ApiV1;

From: "Dario Cantatore" [email protected] To: "apinf" [email protected] Cc: "Matti Leppänen" [email protected], "Author" [email protected] Sent: Friday, June 9, 2017 1:51:44 PM Subject: Re: [apinf/restivus-swagger] Allow Restivus to output Users related endpoint when outputting swagger document (#22)

Adding paths manually definitely works, I am currently using it. Can you paste the code where you tried to use it?

— You are receiving this because you authored the thread. Reply to this email directly, [ https://github.com/apinf/restivus-swagger/issues/22#issuecomment-307358687 | view it on GitHub ] , or [ https://github.com/notifications/unsubscribe-auth/AWL_g15ppCSAsswsFH0UkD_1gHKgEPEBks5sCSPAgaJpZM4NyZwO | mute the thread ] .

matleppa avatar Jun 09 '17 11:06 matleppa

If you see here, this is where it is added: https://github.com/apinf/restivus-swagger/blob/master/server/restivus-swagger.js#L88

I think the latest pull requests might now have been added to the atmosphere package. @brylie can you update the atmosphere package. It shows May 10th as the last update and this was since then. Thanks

dcantatore avatar Jun 09 '17 11:06 dcantatore

@dcantatore you should also have permission to update the Atmosphere package. If you don't mind, go ahead and publish the changes you mention. That way we will know whether your access permission to the APInf organization on Atmosphere is set up correctly.

brylie avatar Jun 11 '17 08:06 brylie

OK, Now I get figured it out, that when adding external paths, the 'paths' section needs to be under 'meta' section. That way I get it working and now also paths containing string 'users' can be included in the generated swagger document. So I think that no changes to Restivus-swagger.js may not necessarily be needed.

Matti

matleppa avatar Jun 12 '17 06:06 matleppa

However, I think that an update in Restivus-swagger documentation is needed. It needs to be clearly indicated, that in case of external paths is used, the definition of 'paths' needs to be inside 'meta' section.

matleppa avatar Jun 13 '17 07:06 matleppa

@matleppa the docs are correct, we just need the most recent version to be pushed to atmosphere. The paths were moved outside the meta in the last PR. So as a heads up, it will move when it is updated soon.

@brylie I see no way to update the atmosphere package when I login to meteor and go to the package.

dcantatore avatar Jun 13 '17 10:06 dcantatore