Skip to content

Mismatch between ToJSON and ToSchema with nullary single-record constructor #81

@jkarni

Description

@jkarni
ghci> data Foo = Foo deriving stock (Generic)
ghci> genericToJSON defaultOptions Foo
Array []
 ghci> encodePretty $ runDeclare (genericDeclareSchema (fromAesonOptions (defaultOptions)) (Proxy :: Proxy Foo)) mempty
"[\n    {},\n    {\n        \"enum\": [\n            \"Foo\"\n        ],\n        \"type\": \"string\"\n    }\n]"

Now, you can get Aeson to behave in the way openapi3 does by using tagSingleConstructors 👍

ghci> genericToJSON (defaultOptions { tagSingleConstructors = True}) Foo
String "Foo"

But with tagSingleConstructors you get a mismatch when the record is not nullary:

ghci> data Bar = Bar Int deriving stock (Generic)
ghci> genericToJSON (defaultOptions { tagSingleConstructors = True}) (Bar 5)
Object (fromList [("contents",Number 5.0),("tag",String "Bar")])
ghci> encodePretty $ runDeclare (genericDeclareSchema (fromAesonOptions (defaultOptions { tagSingleConstructors = True})) (Proxy :: Proxy Bar)) mempty
"[\n    {},\n    {\n        \"maximum\": 9223372036854775807,\n        \"minimum\": -9223372036854775808,\n        \"type\": \"integer\"\n    }\n]"

Which is already known, but means that even if you can modify your encoding to navigate openapi/aeson support, there isn't a single Options that works in all cases.

Am happy to help - though if you have any insights on where to start, let me know!

(See also #55)

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