packages feed

aeson-injector 1.0.0.0 → 1.0.0.1

raw patch · 2 files changed

+131/−2 lines, 2 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

Files

+ README.md view
@@ -0,0 +1,127 @@+# aeson-injector++[![Build Status](https://travis-ci.org/NCrashed/aeson-injector.svg?branch=master)](https://travis-ci.org/NCrashed/aeson-injector)++It is small utility library that is intented to be used in RESTful APIs, especially with [servant](http://haskell-servant.readthedocs.io/en/stable/) and [Swagger](http://swagger.io/). Its main purpose is simple injection of fields into JSONs produced by [aeson](https://hackage.haskell.org/package/aeson) library.++Consider the following common data type in web service developing:++``` haskell+data News = News {+  title :: Text+, body :: Text+, author :: Text+, timestamp :: UTCTime  +}++-- Consider we have simple 'ToJSON' and 'FromJSON' instances+$(deriveJSON defaultOptions ''News) +```++[ToJSON](http://hackage.haskell.org/package/aeson-0.11.2.0/docs/Data-Aeson.html#t:ToJSON) instance produces JSON's like:++``` json+{+  "title": "Awesome piece of news!"+, "body": "Big chunk of text"+, "author": "Just Me"+, "timestamp": "2016-07-26T18:54:42.678999Z"+}+```++Now one can create a simple web server with servant DSL:++``` haskell+type NewsId = Word ++type NewsAPI = +       ReqBody '[JSON] News :> Post '[JSON] NewsId+  :<|> Capture "news-id" NewsId :> Get '[JSON] News+  :<|> "list" :> Get '[JSON] [News]+```++All seems legit, but, wait a second, an API user definitely would like to know id of news in `list` method. One way to do this is declare new type `NewsInfo` with additional field, but it is bad solution as requires to keep extra data type for each resource. ++So, here `aeson-injector` steps in, now you can write:+``` haskell+type NewsAPI = +       ReqBody '[JSON] News :> Post '[JSON] NewsId+  :<|> Capture "news-id" NewsId :> Get '[JSON] News+  :<|> "list" :> Get '[JSON] [WithField "id" NewsId News]+``` ++`WithField "id" NewsId News` or simply `WithId NewsId News` wraps you data type and injects `id` field in produced JSON values:++``` haskell+>>> encode (WithField 42 myNews :: WithField "id" NewsId News)+```++``` json+{+  "id": 42+, "title": "Awesome piece of news!"+, "body": "Big chunk of text"+, "author": "Just Me"+, "timestamp": "2016-07-26T18:54:42.678999Z"+}+```++`WithField` data type has `FromJSON` instance for seamless parsing of data with injected fields and [ToSchema](https://hackage.haskell.org/package/swagger2-2.1/docs/Data-Swagger-Internal-Schema.html#t:ToSchema) instance for [servant-swagger](https://hackage.haskell.org/package/servant-swagger) support.++## Injecting multiple values++The library also has more general data type `WithFields a b` that injects fields of 'toJSON a' into `toJSON b`. ++``` haskell+data NewsPatch = NewsPatch {+  taggs :: [Text]+, rating :: Double+}+$(deriveJSON defaultOptions ''NewsPatch) +```++``` haskell+let myNewsPatch = NewsPatch ["tag1", "tag2"] 42 +in encode $ WithFields myNewsPatch myNews+```++``` json+{+  "title": "Awesome piece of news!"+, "body": "Big chunk of text"+, "author": "Just Me"+, "timestamp": "2016-07-26T18:54:42.678999Z"+, "tags": ["tag1", "tag2"]+, "rating": 42.0+}+```++## Corner cases++Unfortunately, we cannot inject in non object values of produced JSON, so the library creates a wrapper object around non-object value:++``` haskell+encode (WithId 0 "non-object" :: WithId Int String)+```++``` json+{+  "id": 0 +, "value": "non-object"+}+```++The same story is about `WithFields` data type:++``` haskell+encode (WithFields 0 "non-object" :: WithFields Int String)+```++``` json+{+  "injected": 0 +, "value": "non-object"+}+```++For more examples and details, please, follow the haddocks.
aeson-injector.cabal view
@@ -1,7 +1,7 @@ name:                aeson-injector-version:             1.0.0.0+version:             1.0.0.1 synopsis:            Injecting fields into aeson values-description:         See Readme.md+description:         See README.md license:             MIT license-file:        LICENSE author:              Anton Gushcha @@ -14,6 +14,8 @@     GHC == 7.10.3   , GHC == 8.0.1   , GHC == 8.0.2+extra-source-files:+  README.md   source-repository head   type: git