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

Prefix stripping when a $ref is parsed as a Referenced is confusing #95

Open
isomorpheme opened this issue Apr 22, 2024 · 2 comments
Open

Comments

@isomorpheme
Copy link

isomorpheme commented Apr 22, 2024

>>> jsonref = object ["$ref" .= String "#/components/schemas/Foo"]
>>> fromJSON @Reference jsonref
Success (Reference {getReference = "#/components/schemas/Foo"})
>>> fromJSON @(Referenced Schema) jsonref
Success (Ref (Reference {getReference = "Foo"}))

This is not only confusing, but also makes it impossible to get the prefix back if I take the Reference out of a Referenced and try to render it back to JSON. Or dually, if I construct a Referenced with a Reference in it that has the prefix, it'll result in a malformed fragment specifier:

>>> jsonref = object ["$ref" .= String "#/components/schemas/Foo"]
>>> Success ref = fromJSON @Reference jsonref
>>> toJSON (Ref @Schema ref)
Object (fromList [("$ref",String "#/components/schemas/#/components/schemas/Foo")])

For the ToJSON instances, the special casing is implemented here:

referencedToJSON :: ToJSON a => Text -> Referenced a -> Value
referencedToJSON prefix (Ref (Reference ref)) = object [ "$ref" .= (prefix <> ref) ]
referencedToJSON _ (Inline x) = toJSON x
instance ToJSON (Referenced Schema) where toJSON = referencedToJSON "#/components/schemas/"
instance ToJSON (Referenced Param) where toJSON = referencedToJSON "#/components/parameters/"
instance ToJSON (Referenced Response) where toJSON = referencedToJSON "#/components/responses/"
instance ToJSON (Referenced RequestBody) where toJSON = referencedToJSON "#/components/requestBodies/"
instance ToJSON (Referenced Example) where toJSON = referencedToJSON "#/components/examples/"
instance ToJSON (Referenced Header) where toJSON = referencedToJSON "#/components/headers/"
instance ToJSON (Referenced Link) where toJSON = referencedToJSON "#/components/links/"
instance ToJSON (Referenced Callback) where toJSON = referencedToJSON "#/components/callbacks/"

And there's an analogous section for FromJSON elsewhere in the same file. IMO these instances should just do the obvious thing and forward to the appropriate instances on Reference; things like prefix stripping can be done elsewhere.

@isomorpheme
Copy link
Author

isomorpheme commented Apr 22, 2024

Or even better: Reference should contain the type of component as an additional field (i.e. parsed from #/components/{type}/{name}), and the FromJSON instance for Referenced a can then still ensure that the Reference inside a Ref is to the right type of component.

@isomorpheme
Copy link
Author

Just noticed #86 which seems related.

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

No branches or pull requests

1 participant