Aeson requires you to write things twice because it separates encoding and decoding. I’d use something like Autodocodec instead. (it uses aeson only indirectly). And Autodocodec handles Swagger too.
Besides having to write things twice, if you write your parsers manually you run the risk of forgetting a constructor.
autocodec looks great. I have my own library called by-other-names, but it’s not as featureful or mature.
oh very cool; I’d never heard of Autocodec before, thanks for sharing!
This looks great. How do you handle schemas which are not Haskellish though? I find more often than not, I have to write my encoders and decoders by hand because I’m matching some external API, and need things like key names that aren’t valid/canonical in Haskell, or sum type constructions which don’t match the ones aeson expects. I assume the answer is “Autodocodec isn’t for connecting to existing APIs/schemas”, which is fair enough and will be nice for new apps in the future.
As you can see in the example in the readme, the key name is manually specified after the required keyword. In this example, it is “text”:
requiredField "text" "documentation for the text field" .= exampleTextField
If you want the field to not only have a custom key name, but also a custom serialization, you can use make a newtype for the field and give it a custom HasCodec implementation.
There’s some nice stuff in here, but also some code smells to avoid - the main one that jumps out at me is using error in parsers; fail exists for exactly this purpose, and if you write your parser correctly, will provide useful location information for the problem.
updated the blog post to use fail instead of error, thanks again for that callout.
Thanks for the feedback!