-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
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
Export OpenAPI definitions from service examples; affects [dynamic endpoint static] #8966
Conversation
|
scripts/export-openapi-cli.js
Outdated
outParam.name = paramName | ||
// TODO: outParam.description we don't store this yet | ||
outParam.in = paramType | ||
if (paramType === 'path') { | ||
outParam.required = true | ||
} else { | ||
/* | ||
Occasionally we do have required query params, | ||
but at the moment we can't pick this up. | ||
|
||
TODO: Add something to the example format which allows | ||
us to populate this based on the queryParamSchema. | ||
*/ | ||
outParam.required = false |
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.
There's some stuff we just can't really populate from the existing data structure. Rather than try to extend it, move to allowing services to declare openapi path directly.
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.
Could you elaborate on this for me? I'm not confident I understand the logic and comments of the if/else block and the conditionality of required
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 know you resolved this comment, but I think it is worth explaining this one in more detail.
Basically, in our existing examples
array that we attach to service classes, we don't say if a param is required or optional.
For path (or route) params, this doesn't matter. All path params are required in OpenAPI.
For query params, this does matter because in OpenAPI they can be required or optional, and we do have a few services where there are query params that are required at the schema level.
For the moment I'm just setting them all to optional, which is right in most cases but there will be a handful of cases where we are documenting a required query param as optional in the frontend but then requiring it at the schema level. These will need improving later, but the way I want to do this is by moving to declaring an openApi
spec object directly on the service classes, rather than extending the existing examples
object (which already requires some bashing with a hammer to get it into the right format).
* @see https://swagger.io/specification/#paths-object | ||
* @abstract | ||
*/ | ||
static openApi = undefined |
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.
TODO: Moar/better docs, typedef
required: true, | ||
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.
In most cases, this is duplicating information which exists in queryParamSchema
. It would be nice to infer one from the other, but I think I'm not going to get bogged down in that just yet.
Merged in master. Service tests now passing |
staticPreview: { | ||
message: '2', | ||
static openApi = { | ||
'/badge/dynamic/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.
Probably not worth it, at least not as part of this PR, but intuition is that we should either try to extract this from the route
variable that's assigned a value above at the createRoute
call site, or perhaps we should just make the route explicit inline here; It just gives me pause that we've got a hardcoded value here two lines down from where this is set dynamically in a function call, even though I know we're not changing the actual route values ever
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.
Agreed. This comes a few steps further on in the migration plan I laid out.
This is exactly the sort of thing I have in mind when I say "look for ways we can reduce the duplication between the service definition and OpenAPI spec" in the top post - there is definitely information we are specifying twice.
I think I want to have a slightly more holistic view of it all first to arrive at the right abstractions.
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.
The commits in this PR may not be especially helpful. I kind of meandered about a bit. It might be best to just look at the whole diff to review.
I remember reading this back in March, but I'd definitely forgotten it by the time I got around to reviewing. I left a few inline comments/questions/suggestions, several of which were unnecessary and stemmed from reviewing by commit so I closed them out. A couple of other minor thought comments were left open, but none are blocking, especially given how long this has been open and how it is a blocker itself to other work.
The only concern I have is that it feels like there's a lot of what I'll call "domain specifics" around OpenAPI that are definitely unfamiliar to me, and some non-trivial logic in place to reshape some of our existing structures into those domain specifics. I don't think it's great to only have one person understand those well, but I also don't think that's an adequate enough justification to not do anything.
The frontend needs a refresh, that "domain specifics" problem would exist with any solution, and this solution seems as reasonable as any a path forward
Yes. I think there are a couple of challenges with this PR (and the next one). One of them is that it was one of those PRs where I had a vague idea where I was going, but didn't really know exactly what the endgame looked like until I was into the problem (hence the commits kind of wandered around a bit). The second one is that there is a tension between
I'm trying to tackle this in smaller chunks, but the tradeoff of that there are clear improvements that can be made and some of the code I've written here is stop-gap code I hope to delete in the near future. I am also trying to communicate where I envisage we go next with this. I appreciate that it is much clearer to me where we should go next with this, whereas for the person reviewing it you can only really see clearly where I've gone so far.
Yes. This is a good point 👍 Once we drop the a) More clearly document the subset of OpenAPI that we (and contributors) need to declare on a service class and how that subset specifically applies to shields (this is what I'm getting at with the point "update contributing docs for adding new services to reflect new frontend") While we are still declaring an examples array on the service class for 99% of services and haven't quite nailed down how much of the openapi bit needs to be handwritten vs generated, we're not quite in that place yet. I think this will also get a lot easier once there is a decent body of examples to crib from too. In general, I think OpenAPI is probably a good direction of travel though. If you pick a random developer, there is more chance they've some familiarity reading or writing an OpenAPI spec (a widely used standard) than a shields |
I'm going to go ahead and merge this and get back into finishing off #9014 |
Refs #7982
This PR changes lots of things, and also nothing 🙃
One of the things we need to do in order to migrate the frontend to docusaurus-openapi is to produce an OpenAPI spec for each service/endpoint we expose.
This PR does a few main things:
openApi
property directlyexamples
arrayexamples
, so we can do this without having any impact on the existing site.In the interests of keeping changesets reasonably small and easy-ish to review, I'm not doing anything about adding that frontend here - just generating the OpenAPI specs. Also, merging this PR will not change anything about the existing frontend code. Merging this would give us the next piece of the jigsaw to start working on this but we can deploy this without affecting anything.
Next steps from here (may not be exhaustive) are something like:
examples
arrays on service classes toopenApi
objectsopenApi
required/validatedexamples
properties + remove any validation for itexamples
arrays into an OpenAPI spec (this will clean things up a lot)The commits in this PR may not be especially helpful. I kind of meandered about a bit. It might be best to just look at the whole diff to review.
Hopefully this all makes sense as a direction.
There are a couple of failing service tests which are not related to this PR. They are also failing on the daily-tests repo. I'm going to ignore them for now.