-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
feat(rest): add openapi schema consolidation #4365
feat(rest): add openapi schema consolidation #4365
Conversation
39c0a01
to
378d242
Compare
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.
Thank you for the contribution, this will be an awesome improvement! ❤️
I have few comments to address and discuss, see below.
packages/openapi-v3/src/__tests__/unit/consolidate-schema.unit.ts
Outdated
Show resolved
Hide resolved
packages/openapi-v3/src/__tests__/unit/consolidate-schema.unit.ts
Outdated
Show resolved
Hide resolved
packages/openapi-v3/src/__tests__/unit/consolidate-schema.unit.ts
Outdated
Show resolved
Hide resolved
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.
@dougal83 Great effort! The consolidation logic looks reasonable to me.
And for Miroslav's comment https://github.com/strongloop/loopback-next/pull/4365/files#r363800058, I believe creating an enhancer could be a solution. See example in https://github.com/strongloop/loopback-next/pull/4258/files#diff-1903ce348e29b37ce20637fdc02f9d39R45
This comment has been minimized.
This comment has been minimized.
5f394d5
to
1f58b5a
Compare
42e3f97
to
1cc3e98
Compare
Not a problem, we all have finite bandwidth. |
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.
👏
1cc3e98
to
6ae8cde
Compare
@emonddr can you PTAL and check if your comments have been addressed by now? |
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.
Thanks @dougal83
@dougal83, good to merge? I'll leave the honor to you :) |
@dhmlau 👍 I just need to address the following (and ensure test completes as expected): #4365 (comment) |
6ae8cde
to
3fe2df2
Compare
packages/rest/src/__tests__/unit/rest.server/rest.server.open-api-spec.unit.ts
Outdated
Show resolved
Hide resolved
packages/rest/src/__tests__/unit/rest.server/rest.server.open-api-spec.unit.ts
Outdated
Show resolved
Hide resolved
) | ||
.build(); | ||
|
||
const spec = await server.getApiSpec(); |
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.
@dougal83 This will remove spec.paths
as we try to build openapi spec from the handler. See https://github.com/strongloop/loopback-next/blob/master/packages/rest/src/rest.server.ts#L800.
You probably have to add a route with the expected api spec.
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.
@dougal83 The following code works for me.
- We need to call server.route() to set up a real route
- server.route() needs to be called before
start
.
context('options', () => {
it('disables consolidator if consolidate is set to false', async () => {
const options: {rest: RestServerConfig} = {
rest: {openApiSpec: {consolidate: false}},
};
options.rest = givenHttpServerConfig(options.rest);
app = new Application(options);
app.component(RestComponent);
server = await app.getServer(RestServer);
const EXPECTED_SPEC = anOpenApiSpec()
.withOperation(
'get',
'/',
anOperationSpec().withResponse(200, {
description: 'Example',
content: {
'application/json': {
schema: {
title: 'loopback.example',
properties: {
test: {
type: 'string',
},
},
},
},
},
}),
)
.build();
server.route('get', '/', EXPECTED_SPEC.paths['/'].get, () => {});
await server.start();
const spec = await server.getApiSpec();
expect(spec).to.eql(EXPECTED_SPEC);
await server.stop();
});
it('runs consolidator if consolidate is set to true', async () => {
const options: {rest: RestServerConfig} = {
rest: {openApiSpec: {consolidate: true}},
};
options.rest = givenHttpServerConfig(options.rest);
app = new Application(options);
app.component(RestComponent);
server = await app.getServer(RestServer);
const EXPECTED_SPEC = anOpenApiSpec()
.withOperation(
'get',
'/',
anOperationSpec().withResponse(200, {
description: 'Example',
content: {
'application/json': {
schema: {
$ref: '#/components/schemas/loopback.example',
},
},
},
}),
)
.withComponents(
aComponentsSpec().withSchema('loopback.example', {
title: 'loopback.example',
properties: {
test: {
type: 'string',
},
},
}),
)
.build();
server.route(
'get',
'/',
anOperationSpec()
.withResponse(200, {
description: 'Example',
content: {
'application/json': {
schema: {
title: 'loopback.example',
properties: {
test: {
type: 'string',
},
},
},
},
},
})
.build(),
() => {},
);
await app.start();
const spec = await server.getApiSpec();
expect(spec).to.eql(EXPECTED_SPEC);
await app.stop();
});
});
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.
BTW, this is not really a unit test anymore. We probably should move it to integration
.
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.
thank you @raymondfeng . In getApiSpec
, spec.paths
and spec.components.schemas
are not preserved, is it intended?
I remember we discussed this before, if the paths and schemas should be kept I can submit a PR to fix it.
(the discussion here is not related to PR I can open a new issue if we need more opinions)
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.
For the rest configurations:
the unit tests are added in tests/unit/rest.server/rest.server.unit.ts
and integration tests are in tests/integration/rest.server.integration.ts
links point to the existing options tests.
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.
EDIT: I will address The following code works for me. onward as missed.
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.
@raymondfeng Thank you very much for your guidance! 👍
@jannyHou Thank you for your help! Could you please check that the tests are located in the correct place now? I've no formal training on tests so I'm really just hacking.
3fe2df2
to
619d62f
Compare
@jannyHou Thanks for pointers. Could you please check changes to |
I've just noticed comments I've missed via notifications. Will revisit pr tomorrow to double check. (I've not ignored them) |
cce2478
to
e1ccf4b
Compare
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 looks fantastic.
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.
Great effort and patience. Please squash all commits into one before merge.
e1ccf4b
to
a0a6c22
Compare
@raymondfeng @bajtos Quick query. Should I drop the following commit as it was not used? a0a6c22 |
I would keep it. |
Add openapi schema enhancer to rest server. Consolidates openapi schema, by creating references to schema to reduce duplication. Can be disabled by setting rest option openApiSpec.consolidate to false. feat(openapi-v3): getEnhancerByName accept generic parameter Signed-off-by: Douglas McConnachie <[email protected]>
a0a6c22
to
1990c7b
Compare
Add openapi schema consolidation to rest server as core OAS Enhancer
Implements #4328
See also #4290 (as follows)
For longer term, I would like our REST layer to be smarter and able to automatically extract schemas used in multiple places into
/components/schemas
and replace them with$ref
at usage points.This logic can work as follows:
/components/schemas
./components/schemas
in step 3 with$ref
. (I think this could be optimized to avoid the second spec tree scan, but that could be done later.)Originally posted by @bajtos in #4290 (comment)
Checklist
npm test
passes on your machine