Skip to content

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

Description

@isomorpheme
>>> 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.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions