biocad / openapi3

OpenAPI 3.0 data model
BSD 3-Clause "New" or "Revised" License
39 stars 53 forks source link

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

Open isomorpheme opened 5 months ago

isomorpheme commented 5 months ago
>>> 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: https://github.com/biocad/openapi3/blob/efb9a50c8d808dd684fe2e04ff0b0168fc0f097a/src/Data/OpenApi/Internal.hs#L1427-L1438

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 commented 5 months ago

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 commented 5 months ago

Just noticed #86 which seems related.