Copyright | (c) 2017 Shinya Takahashi |
---|---|
License | MIT |
Maintainer | Shinya Takahashi <[email protected]> |
Stability | experimental |
Portability | portable |
Safe Haskell | None |
Language | Haskell2010 |
Refty
Description
Reference + Entity = Refty ♡
Formatted JSON generator for API server inspired by normalizr.
- type Key = Text
- type Identifier a b = a -> b
- data Entity a
- = SingleEntity a
- | ListEntity [a]
- data Resource a b = Resource Key (Identifier a b) (Entity a)
- data Reference a b
- = SelfRef Key
- | HasOneRef Key (Identifier a b)
- | HasManyRef Key (Identifier a b)
- data Builder = (ToJSON a, ToJSON b, ToJSONKey b, Ord b) => Builder (Resource a b) [Reference a b]
- newtype Refty = Refty [Builder]
- singleEntity :: ToJSON a => a -> Entity a
- listEntity :: ToJSON a => [a] -> Entity a
- resource :: (ToJSON a, ToJSON b, ToJSONKey b, Ord b) => Key -> Identifier a b -> Entity a -> Resource a b
- selfRef :: (ToJSON a, ToJSON b, ToJSONKey b, Ord b) => Key -> Reference a b
- hasOneRef :: (ToJSON a, ToJSON b, ToJSONKey b, Ord b) => Key -> Identifier a b -> Reference a b
- hasManyRef :: (ToJSON a, ToJSON b, ToJSONKey b, Ord b) => Key -> Identifier a b -> Reference a b
- builder :: (ToJSON a, ToJSON b, ToJSONKey b, Ord b) => Resource a b -> [Reference a b] -> Builder
- refty :: [Builder] -> Refty
Usage
We will generate json like:
{ "entities": { "users": { "1": { "id": 1, "name": "Lelouch" }, "2": { "id": 2, "name": "Suzaku" }, "3": { "id": 3, "name": "Jeremiah" } }, "comments": { "1": { "id": 1, "body": "Hello", "userId": 1 }, "4": { "id": 4, "body": "Foo", "userId": 1 }, "2": { "id": 2, "body": "World", "userId": 1 }, "3": { "id": 3, "body": ":)", "userId": 3 } } }, "references": { "self": [ 2, 1, 3 ], "userComments": { "1": [ 1, 4, 2 ], "3": [ 3 ] } } }
First, define data types like:
User.hs:
import Data.Aeson import Data.Text as T import GHC.Generics (Generic) data User = User { id :: Int , name :: T.Text } deriving (Generic, Show) instance ToJSON User
Comment.hs:
import Data.Aeson import Data.Text as T import GHC.Generics (Generic) data Comment = Comment { id :: Int , userId :: Int , body :: T.Text } deriving (Generic, Show) instance ToJSON Comment
Next, create JSON.
import Data.Aeson import Refty import qualified User as U import qualified Comment as C -- Sample data users = [ U.User 2 "Suzaku" , U.User 1 "Lelouch" , U.User 3 "Jeremiah" ] comments = [ C.Comment 1 1 "Hello" , C.Comment 4 1 "Foo" , C.Comment 2 1 "World" , C.Comment 3 3 ":)" ] encode $ refty [ builder (resource "users" U.id $ listEntity users) [ selfRef "self" ] , builder (resource "comments" C.id $ listEntity comments) [ hasManyRef "userComments" C.userId ] ]
Data types
type Identifier a b = a -> b Source #
Identifier getter of entity.
Basic entity information.
Constructors
Resource Key (Identifier a b) (Entity a) |
Reference information of entity.
Constructors
SelfRef Key | |
HasOneRef Key (Identifier a b) | |
HasManyRef Key (Identifier a b) |
Information builder related entity.
Constructor functions
singleEntity :: ToJSON a => a -> Entity a Source #
Constructor function for Entity.
listEntity :: ToJSON a => [a] -> Entity a Source #
Constructor function for Entity.
resource :: (ToJSON a, ToJSON b, ToJSONKey b, Ord b) => Key -> Identifier a b -> Entity a -> Resource a b Source #
Constructor function for Resource.
selfRef :: (ToJSON a, ToJSON b, ToJSONKey b, Ord b) => Key -> Reference a b Source #
Constructor function for Reference.
hasOneRef :: (ToJSON a, ToJSON b, ToJSONKey b, Ord b) => Key -> Identifier a b -> Reference a b Source #
Constructor function for Reference.
hasManyRef :: (ToJSON a, ToJSON b, ToJSONKey b, Ord b) => Key -> Identifier a b -> Reference a b Source #
Constructor function for Reference.