JsonApi.Resource exposes the Resource
type and functions to get and set information
for your resources.
JsonApi.Internal.ResourceInfo.ResourceInfo
The Resource
represents a resource. It is passed to your resource decoders, but you can also use it to encode resources to json api, via a Document
.
It contains useful information for decoding and encoding your resource: resource id
, links
, attributes
, relationships
, ...
_Example of json api
{
"data": [
{
"type": "users",
"id": "13608770-76dd-47e5-a1c4-4d0d9c2483ad",
"links": {
"self": "http://link-to-user",
"profile": "http://link-to-user-profile"
},
"attributes": {
"firstname": "John",
"lastname": "Doe",
"gender": "male"
},
"relationships": {}
}
]
}
And how to build it with the JsonApi.Resource
module:
build "users"
|> withId "13608770-76dd-47e5-a1c4-4d0d9c2483ad"
|> withLinks
(Dict.fromList
[ ( "self", "http://link-to-user" )
, ( "profile", "http://link-to-user-profile" )
]
)
|> withAttributes
[ ( "firstname", string "John" )
, ( "lastname", string "Doe" )
, ( "gender", string "male" )
]
JsonApi.Internal.ResourceInfo.OneOrManyRelationships
This type is used to represent either one or many relationships in your Resource
object.
See withRelationship
function for more information
Relationship's data object. It's a variant type because in a relationship
the data
field can either: be null, have one relationship, have many relationships.
See getRelationshipsDesc
for more information
{ id : String
, type_ : String
}
Description of the data
object in a relationship
object.
Contains the id
of the relationship and it's type
See getRelationshipsDesc
for more information
{ data : OneOrMoreRelationshipData
, links : Dict String String
}
The description of a relationship in the relationships
field of the jsonapi object.
For instance (in jsonapi):
"relationships": {
"creator": {
"data": {
"type": "creators",
"id": "22208770-76dd-47e5-a1c4-4d0d9c2483ad"
},
"links": {
"related": "http://link-to-creator/1"
}
}
}
This type contains the links defined in the relationship and the data
object of
the relationship
See getRelationshipsDesc
for more information
build : String -> Resource
Builds a new Resource
with the specified type name
You can build your resources like this:
myResource : Post -> Resource
myResource post =
build "posts"
|> withId "post-1"
|> withLinks (Dict.fromList [ ( "self", "http://url-to-post/1" ) ])
fromResource : String -> Resource -> Resource
Builds a new Resource
from the specified Resource
and with the specified type name
You can build your resources like this:
myResource : Resource -> Resource
myResource resource =
fromResource "posts" resource
id : Resource -> String
Returns the id
of your resource.
From the json example above, id
will return 13608770-76dd-47e5-a1c4-4d0d9c2483ad
links : Resource -> Dict String String
Returns the links
of your resource.
From the json example above, links
will return a Dict
with this value:
[ ( "self", "http://link-to-user" )
, ( "profile", "http://link-to-user-profile" )
]
resType : Resource -> String
Returns the type
of your resource.
From the json example above, type_
will return users
getRelationshipsDesc : Resource -> Dict String RelationshipDesc
Returns the relationships description of your resource.
This is not a way to decode a relationship, only a quick way to get the relationship ids and types
type alias Post =
{ id : String
, links : Dict String String
, title : String
, content : String
, relationships : Dict String JsonApi.Resource.RelationshipDesc
}
decoder : Resource -> Decoder Post
decoder resourceInfo =
map5 Post
(succeed (JsonApi.Resource.id resourceInfo))
(succeed (JsonApi.Resource.links resourceInfo))
(field "title" string)
(field "content" string)
(succeed (JsonApi.Resource.getRelationshipsDesc resourceInfo))
Say the relationships for this post are:
"relationships": {
"creator": {
"data": {
"type": "creators",
"id": "22208770-76dd-47e5-a1c4-4d0d9c2483ad"
},
"links": {
"related": "http://link-to-creator/1"
}
},
"comments": {
"links": {},
"data": [
{
"type": "comment",
"id": "22208770-76dd-47e5-a1c4-4d0d9c2483ab"
},
{
"type": "comment",
"id": "cb0759b0-03ab-4291-b067-84a9017fea6f"
}
]
}
}
Then you will get these information:
Dict.get "creator" post.relationships
Just
{ links = [ ( "related", "http://link-to-creator/1" ) ]
, data =
JsonApi.Resource.One
{ id = "22208770-76dd-47e5-a1c4-4d0d9c2483ad"
, type_ = "creators"
}
}
Dict.get "comments" post.relationships
Just
{ links = []
, data =
JsonApi.Resource.Many
[ { id = "22208770-76dd-47e5-a1c4-4d0d9c2483ab"
, type_ = "comment"
}
, { id = "cb0759b0-03ab-4291-b067-84a9017fea6f"
, type_ = "comment"
}
]
}
withId : String -> Resource -> Resource
Sets the id of the Resource
object
myResource : Post -> Resource
myResource post =
build "posts"
|> withId "post-1"
withLinks : Dict String String -> Resource -> Resource
Sets the links of the Resource
object
myResource : Post -> Resource
myResource post =
build "posts"
|> withLinks (Dict.fromList [ ( "self", "http://url-to-post/1" ) ])
withAttributes : List ( String, Json.Encode.Value ) -> Resource -> Resource
Sets the attributes of the Resource
object.
This is the payload of your resource.
myResource : Post -> Resource
myResource post =
build "posts"
|> withAttributes
[ ( "firstname", string "John" )
, ( "lastname", string "Doe" )
, ( "gender", string "male" )
]
withRelationship : String -> OneOrManyRelationships -> Resource -> Resource
Adds a relationship in the Resource
object.
You have to pass it the name of the relationship and a description of the relationship resource (See relationship
and relationships
)
myResource : Post -> Resource
myResource post =
build "posts"
|> withRelationship "creators" (relationship creator.id (creatorResource creator))
relationship : String -> Resource -> OneOrManyRelationships
Defines a relationship that can then be added to its parent Resource
.
It takes the id
of the resource and the resource.
creatorResource : Creator -> Resource
creatorResource creator =
build "creator"
|> withAttributes [ ( "firstname", string creator.firstname ) ]
myResource : Post -> Resource
myResource post =
build "posts"
|> withRelationship "creators" (relationship creator.id (creatorResource creator))
relationships : List ( String, Resource ) -> OneOrManyRelationships
Defines a list of relationships that can then be added to a parent Resource
.
It takes a List
of Tuple
s with the id
of the resource and the resource.
commentResource : Comment -> Resource
commentResource comment =
build "comment"
|> withAttributes [ ( "content", string comment.content ) ]
myResource : Post -> Resource
myResource post =
build "posts"
|> withRelationship "comments" (relationships (List.map (\comment -> ( "comment", commentResource comment )) comments))