Reputation: 1056
I am building a REST API that exposes information about online courses to users. Here is the general structure of a course:
Course > Units > Lessons > Activities
I'm trying to make my JSON response structure HAL compliant, but i'm unsure if i'm doing it correctly.
Which of the following is correct:
{
“kind”: “clms#course”,
“id”: long,
“course-name”: string,
“course-icon”: string,
“product-name”: string,
“product-icon”: string,
“_links”: {
“self”: {“href” : string},
“unitlist”: {“href” : string} // This is a link to list of units for the course.
}
}
Or is the link to the list of units an _embedded resource?
{
“kind”: “clms#course”,
“id”: long,
“course-name”: string,
“course-icon”: string,
“product-name”: string,
“product-icon”: string,
“_links”: {
“self”: {“href” : string},
}
"_embedded": {
“unitlist”: {“href” : string} // This is a link to list of units for the course.
}
}
Or are both wrong!? Any help appreciated.
Cheers, Ollie
Upvotes: 1
Views: 995
Reputation: 4010
Few things. Let me take you through the process, and it might help.
Start with just the links and their relationships. There's a course, it has units. So each unit relates to a course as a unit. use that as your relationship name. so:
{
“kind”: “clms#course”,
“id”: long,
“course-name”: string,
“course-icon”: string,
“product-name”: string,
“product-icon”: string,
“_links”: {
“self”: {“href” : string},
“unit”: [
{“href” : url-of-first-unit},
{“href” : url-of-second-unit},
{“href” : url-of-third-unit},
...
]
}
}
but unit is not an IANA registered link relationship, so it should actually be a URI, or curried to a URI:
“_links”: {
“self”: {“href” : string},
"curies" : [
{"href" : "http://youndomain/rels/{rel}", name : "x" }
],
“x:unit”: [
{“href” : url-of-first-unit},
{“href” : url-of-second-unit},
{“href” : url-of-third-unit},
...
]
}
that's a little confusing, but it makes it so your unit is "namespaced" and it's own thing which is good.
Now realize that retrieving all of those units individually would be painful. I'll assume that in your UI you want to show the units right along with the courses, so HAL let's you embed those relationships:
{
“kind”: “clms#course”,
“id”: long,
“course-name”: string,
“course-icon”: string,
“product-name”: string,
“product-icon”: string,
“_links”: {
“self”: {“href” : string},
"curies" : [
{"href" : "http://youndomain/rels/{rel}", name : "x" }
],
“x:unit”: [
{“href” : url-of-first-unit},
{“href” : url-of-second-unit},
{“href” : url-of-third-unit},
...
]
},
"_embedded" : {
“x:unit”: [
{ some json representing the unit located at url-of-first-unit},
{ some json representing the unit located at url-of-second-unit},
{ some json representing the unit located at url-of-third-unit},
...
]
}
}
Now a client can get the unit's my checking embedded instead of checking links. In fact since it's embedded, there's really no reason to include the links anymore (unless you know a client is depending on them):
{
“kind”: “clms#course”,
“id”: long,
“course-name”: string,
“course-icon”: string,
“product-name”: string,
“product-icon”: string,
“_links”: {
“self”: {“href” : string},
"curies" : [
{"href" : "http://youndomain/rels/{rel}", name : "x" }
],
},
"_embedded" : {
“x:unit”: [
{ some json representing the unit located at url-of-first-unit},
{ some json representing the unit located at url-of-second-unit},
{ some json representing the unit located at url-of-third-unit},
...
]
}
}
So now the client has them available as an embedded resource and does not need to retrieve the resources with http requests.
Overall i'd suggest starting with links to everything, and optimize for your use cases by embedded resources.
Few extra notes:
Upvotes: 1