-
Notifications
You must be signed in to change notification settings - Fork 1.1k
oas3/upgrade #1067
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
oas3/upgrade #1067
Conversation
744c855 to
5e3937a
Compare
shimks
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks 😎.
I think there are a couple of stuff that needs to be mentioned. Here's a list:
- we need tests for the new parser logic (the one with
requestBodyindexing) - is todoSchema used anywhere else other than in the lines you've deleted? If it isn't, should we get rid of it or nah
- have you checked for upgrading imports in the READMEs? If you did and haven't found any, ignore my comment.
|
While I was reviewing the changes, I came across the issue of content type for YAML and OpenAPI Spec documents. While it's probably not relevant to the changes made in this pull request, I'd still like to post what I found for future use. Ideally, Eventually, when OpenAPI spec working group decides on the content type for OAI documents (see OAI/OpenAPI-Specification#110), we should switch to that one instead. Their latest proposal (21 days old, see OAI/OpenAPI-Specification#110 (comment)): With an optional version parameter: As for |
bajtos
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is awesome 🎉
The last commit seems to contain formatting/linting fixes for previous commits, I assume you are going to squash the commits before landing.
Should we remove swagger (v2) related packages as part of this pull request too?
I have few (hopefully minor) comments to address, see below.
| content: { | ||
| // TODO(janny) will change it to a default value | ||
| // after we figure out the plan for content type | ||
| '*/*': { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IIRC, the intent of withStringResponse was to describe a response that returns text/plain, see https://github.com/strongloop/loopback-next/blob/ba13710378fd288550989135bc4447e26183b900/packages/rest/src/writer.ts#L47-L48
I am proposing to use text/plain instead of */*.
packages/rest/src/parser.ts
Outdated
|
|
||
| let requestBodyIndex: number = -1; | ||
| if (hasArgumentsFromBody(operationSpec)) { | ||
| const i = (<RequestBodyObject>operationSpec.requestBody)[ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is it necessary to cast operationSpec.requestBody to RequestBodyObject? I would expect the type definition for operation specs to already specify requestBody as being of type RequestBodyObject.
What am I missing?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
requestBody could be RequestBodyObject or ReferenceObject, see: https://github.com/metadevpro/openapi3-ts/blob/master/src/model/OpenApi.ts#L99
I specify the type here to avoid resolving the ReferenceObject, I will add a comment here.
packages/rest/src/parser.ts
Outdated
| args.push(body); | ||
| return; | ||
| } | ||
| for (const arg of paramArgs) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Have you considered using Array.prototype.splice to insert the body parameter at the given index?
Something along the following lines:
paramArgs.splice(requestBodyIndex, 0, body);
args = paramArgs;
packages/rest/src/rest-server.ts
Outdated
| if (options.version !== '3.0.0') { | ||
| throw new Error( | ||
| 'Swagger2 spec is not supported in rest server, ' + | ||
| 'please upgrade it to OpenAPI3', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you need to disable routes /swagger.json and /swagger.yaml - these are the users of options.version = '2.0'. See https://github.com/strongloop/loopback-next/blob/ba13710378fd288550989135bc4447e26183b900/packages/rest/src/rest-server.ts#L48-L53
| responses: { | ||
| 200: { | ||
| schema: {type: 'string'}, | ||
| content: {'*/*': {schema: {type: 'string'}}}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Similarly here, the endpoint should specify text/plain as the response content type.
| responses: { | ||
| 200: { | ||
| schema: {type: 'string'}, | ||
| content: {'*/*': {schema: {type: 'string'}}}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ditto.
| description: 'The string result.', | ||
| schema: { type: 'string' } | ||
| } | ||
| }, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it a valid controller spec when there are no responses described?
IMO, we should preserve the 200 response and describe it as returning text/plain content type.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is probably a bug, I manually wrote the code to generate the spec from getControllerSpec().
According to the code in controller-spec
the responses should be {}.
we should preserve the 200 response and describe it as returning text/plain content type
Right now unless user provides responses spec in @operation/@api, we don't generate responses object for them....
We need a story/epic for adding responses leveraging controller function's return type.
I understand that it's a huge gap, and if you remember the two line of commented code I forgot to delete in the previous PR, I tried to add some simple discovery for the response schema, but stopped after realizing it's a big feature.
I am creating a story for it. Sorry I know this is a big gap but it's not possible to fit it in this PR or the upgrade story :(
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Related story: #1086
| "dependencies": { | ||
| "@loopback/context": "^0.1.2", | ||
| "@loopback/core": "^0.1.2", | ||
| "@loopback/openapi-v3": "^0.1.1", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we re-export decorators like get and param from @loopback/rest so that LoopBack consumers don't have to upgrade when we change the underlying spec (like from Swagger to OpenAPI)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am also thinking of re-exporting it or not doing that.
LoopBack consumers don't have to upgrade when we change the underlying spec (like from Swagger to OpenAPI)
Actually I would like to encourage them to change the importing module, like how they import @model and @property from @loopback/repository.
And we re-exported it before to avoid breaking change, while v2-->v3 upgrade is a breaking change anyway, so if we want to decouple controller decorators and rest package, this is a proper time.
Since this could be a user experience issue, I would like to hear more opinions from the team @strongloop/loopback-next :
Would you prefer to import controller decorators (e.g. @get, @post, @param, @requestBody) from @loopback/rest or @loopback/openapi-v3?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it's better to re-export the decorators from rest since it simplifies the user experience by abstracting away the underlying package.
As a user trying to create REST APIs, I want to be able to use the rest package to do so without having to understand what OpenAPI is / what it does, etc. I just want to be able to create the api.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1 for what @virkt25 said 👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
cool @virkt25 thanks for the feedback :) Added the export code.
b-admike
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice work! I've left some feedback
| requestBody, | ||
| } from '@loopback/openapi-v3'; | ||
| import {HttpErrors} from '@loopback/rest'; | ||
| import {TodoSchema, Todo} from '../models'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we get rid of TodoSchema definition if it is not used for anything else?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@b-admike ah, answered ^ in the last part of comment #1067 (comment)
packages/rest/src/parser.ts
Outdated
| pathParams: PathParameterValues, | ||
| body?: MaybeBody, | ||
| ): OperationArgs { | ||
| const args: OperationArgs = []; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Guess we don't need args anymore since we have paramArgs defined below
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
args is for keeping all arguments, including parameters + requestBody
paramArgs is for keeping parameters only.
| }); | ||
|
|
||
| context('with a body-parameter route', () => { | ||
| context('with a body request route', () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I presume there are tests coming here :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
don't trust the git compare :( the old test cases are updated, if you are talking about the acceptance tests, added them in commit 8e7570c :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think @b-admike might be referring to the formdata tests. I don't see them in the above commit. Does this have to do with how V3 handles the form data?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@virkt25 V3 doesn't have a concept of "form data", it always treats requestBody as a whole, you can describe requestBody by any complicated schema, but you could not specify an argument as part of a requestBody schema. So I refactored all the V2 "form data" + "request body" tests to be V3 "request body" tests.
packages/testlab/package.json
Outdated
| "sinon": "^4.1.2", | ||
| "supertest": "^3.0.0", | ||
| "swagger-parser": "^4.0.1" | ||
| "swagger-parser": "^4.0.1", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we have any use for swagger-parser anymore?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
good catch nope
Could you elaborate more about this? I know the document(loopback.io) need a bunch of updates for code example, but could not think of any READMEs needs update, besides And for the tests, good point in term of the acceptance tests 👍 added in commit 70019b8 The index testing is covered in integration test All those requestBody tests in
I think @b-admike also raise the same concern. I have seen lots of discussions/PRs regarding |
Yep I will squash all commits to one, broke them into smaller ones to make review easier.
I prefer to leave them in this PR and I'll create anther PR doing:
|
| @@ -0,0 +1,71 @@ | |||
| ### Create your controller | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OOPS accidentally added it when rebase, deleted it in fc6b3d1
The packages will be always preserved in git history. People wishing to obtain the old code should check out and older SHA revision (commit). If you want to make the discovery process easier, then you can create a named tag (or a branch?) pointing to the latest commit before the code was deleted. It would be nice to update the README of v2 packages to say that they are deprecated and no longer maintained, and publish a new version of each deprecated package to npmjs, so that e.g. this page shows the current status: https://www.npmjs.com/package/@loopback/openapi-v2 |
1c72cf4 to
7b9a7fa
Compare
👍 @bajtos I added a deprecation notice in this PR for |
bajtos
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am suggesting a slightly different notice text:
This package has been deprecated in favor of OpenAPI Spec version 3.0.0, we are no longer maintaining it.
packages/openapi-spec/README.md
Outdated
| @@ -1,3 +1,7 @@ | |||
| ## DEPRECATION NOTICE | |||
|
|
|||
| This package is deprecated since we upgrade loopback-next to use openapi 3.0.0 starndard. | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
typo, should be standard.
packages/openapi-v2/README.md
Outdated
| @@ -1,3 +1,7 @@ | |||
| ## DEPRECATION NOTICE | |||
|
|
|||
| This package is deprecated since we upgrade loopback-next to use openapi 3.0.0 starndard. | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
typo, should be standard.
| @@ -1,71 +0,0 @@ | |||
| ### Create your controller | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are you intentionally removing 7-controller.md file? Isn't this going to break Kevin's tutorial on loopback.io?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@bajtos my bad rebase added it in the first commit, so I removed it in this fix commit, I checked https://github.com/strongloop/loopback-next/tree/master/packages/example-getting-started/docs, that doc should be renamed/replaced by controller.md, but I will double check with @kjdelisle
| '/openapi.json': {version: '3.0.0', format: 'json'}, | ||
| '/openapi.yaml': {version: '3.0.0', format: 'yaml'}, | ||
| '/swagger.json': {version: '2.0', format: 'json'}, | ||
| '/swagger.yaml': {version: '2.0', format: 'yaml'}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When cleaning up git history, please make sure that the commit message mentions the breaking change - removal of GET /swagger.{json,yaml} endpoints.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will add list all breaking changes in the commit message ^
|
Added all the breaking changes in commit message: 6074525 And I will squash commits into one when merging |
|
+1 for using @bajtos version of the commit message since it's more general. Just have a comment about form-data tests. Apart from that LGTM! 👍 |
fb72ac3 to
88e19bc
Compare
|
Oops. I meant deprecation notice not commit message. |
|
@virkt25 ah I see, good catch, I missed that message. Re-phrased it to Miroslav's version. |
b-admike
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🚢🇮🇹
* (rest) Remove GET /swagger.json and GET /swagger.yaml * (all packages) Upgrade packages from using @loopback/openapi-v2 to @loopback/openapi-v3 * (all pakcages) Upgrade packages from using @loopback/openapi-spec to @loopback/openapi-v3-types * (testlab) Replace Swagger validator by OAI3 validator provided by swagger2openapi
connect to: #753
Description
Upgrade the whole project to use
openapi-v3This is the 4rd PR of prototype PR: #916 (comment)
connect to issue: #753
Review
I would suggest review by each commit.
Next
openapi-spec-builder-->openapi-v3-spec-builderopenapi-spec-->openapi-v2-typesChecklist
npm testpasses on your machinepackages/cliwere updatedpackages/example-*were updated