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

Ensure that query param types are not inlined in OpenAPI spec #861

Merged
merged 3 commits into from
Feb 2, 2023

Conversation

georgefst
Copy link
Contributor

@georgefst georgefst commented Jan 31, 2023

A workaround for biocad/servant-openapi3#37.

As can be seen from the changes to openapi.json, this removes some duplication in the spec. One particular effect is that Orval-generated TypeScript bindings now use a common concise name for all occurrences of Level, InputAction and NoInputAction.

@georgefst georgefst force-pushed the georgefst/openapi-level branch from 8fbea88 to 92a5b2e Compare January 31, 2023 15:48
As can be seen from the changes to `openapi.json`, this removes some duplication in the spec. One particular effect is that Orval-generated TypeScript bindings now use a common concise name for all occurrences of `Level`, `InputAction` and `NoInputAction`.
@georgefst georgefst force-pushed the georgefst/openapi-level branch from 92a5b2e to 89fc6ae Compare January 31, 2023 19:06
@georgefst georgefst changed the title hardcode param schemas Ensure that query param types are not inlined in OpenAPI spec Jan 31, 2023
@georgefst georgefst marked this pull request as ready for review January 31, 2023 19:08
@georgefst georgefst requested a review from a team January 31, 2023 19:08
Comment on lines 126 to 130
{- This is a workaround for an upstream issue: https://github.com/biocad/servant-openapi3/issues/37.
Given a type, and some query parameters of that type,
this ensures that the specification of each parameter references a common schema,
instead of inlining it.
-}
Copy link
Contributor

Choose a reason for hiding this comment

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

This sounds sensible. It does mean that we have to manually enumerate them (and thus potentially miss some). Another approach would be to replace any inlined thing of the correct shape with a reference (less flexible -- perhaps we want some of them inlined / there are two different types that happen to serialise the same).

Comment on lines 131 to 142
refParamSchemas :: forall a. ToSchema a => [(FilePath, Text)] -> OpenApi -> OpenApi
refParamSchemas params api =
api
& #components % #schemas %~ IOHM.insert name (toSchema $ Proxy @a)
& #paths %~ foldr ((.) . uncurry (flip adjustParam)) identity params
where
adjustParam paramName =
IOHM.adjust $
#post % mapped % #parameters % mapped %~ \case
Inline x | x ^. #name == paramName -> Inline $ x & #schema ?~ Ref (Reference name)
p -> p
name = show $ typeRep @a
Copy link
Contributor

Choose a reason for hiding this comment

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

Small worries (that happen not to be problematic given how we are using this):

Copy link
Contributor Author

Choose a reason for hiding this comment

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

These are all good points, as is #861 (comment).

I've got my fingers crossed that this gets fixed upstream (even if that means fixing it ourselves) before we have to make this workaround any more general.

Copy link
Contributor

Choose a reason for hiding this comment

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

I'm happy with this as-is, but let's add some comments documenting the lack of generality (i.e. manually enumerate, only look at puts)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

refParamSchemas params api =
api
& #components % #schemas %~ IOHM.insert name (toSchema $ Proxy @a)
& #paths %~ foldr ((.) . uncurry (flip adjustParam)) identity params
Copy link
Contributor

Choose a reason for hiding this comment

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

To me, this is rather inscrutable. Perhaps worth pulling out a helper for "compose this list of functions" compose = appEndo . foldMap' Endo?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@@ -127,6 +127,10 @@ openAPIInfo =
Given a type, and some query parameters of that type,
this ensures that the specification of each parameter references a common schema,
instead of inlining it.
This could be made more general, (visit non-POST endpoints,
modify `show . typeRep` output when it contains `'` to match `openapi3`,
Copy link
Contributor

Choose a reason for hiding this comment

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

You mean (a literal space) here (openapi3 does not do anything special with ' and generates broken schemas because of it, but it does replace spaces with underscores)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ah, thanks, maybe I should have read that issue properly. Fixed.

@georgefst georgefst force-pushed the georgefst/openapi-level branch from 88c7b8a to 491ea6d Compare February 2, 2023 15:28
Copy link
Contributor

@brprice brprice left a comment

Choose a reason for hiding this comment

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

LGTM now

@georgefst georgefst added this pull request to the merge queue Feb 2, 2023
Merged via the queue into main with commit 536ecc7 Feb 2, 2023
@georgefst georgefst deleted the georgefst/openapi-level branch February 2, 2023 16:02
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.

2 participants