1

The last year I have been working on a hobby project. I use Spring MVC (4 at the moment) and I have created a web service trying to adhere to REST principles.

I have a resource named Athlete that have relations to other resources such as SportEvent, 'Trainer` and so on.

These relations are not embedded in the athlete resource. Instead they are links. This is an example:

{
    "firstName": "James",
    "lastName":"Smith",
    "links": [{
        "rel": "trainer",
        "href" : "http://somehost.com/sport/trainers/4"
    },
    {
        "rel": "sport-events",
        "href" : "http://somehost.com/sport/athletes/4/sport-events"
    }]
}

I am currently writing the client side in AngularJS and I am going to consume this API. It was during this I discovered something that I hadn't thought through. How are the client actually going to consume this?

Let say I am building the regular detail page for a athlete. I want to show the athletes trainer as well. I have to somehow have a HTTP client library that is able to resolve the relations I want and attach the response to the "parent" resource (the one that has the relations) in a recursive manner.

How is it actually intended to navigate an API like this? You can't follow links without explicitly stating which you want to follow? Because if you don't you will end up creating potentially huge objects. You want some kind of criteriea?

I am definitly interested in how to actually consume my API (sounds weird, but I had not thought through the actual process of resolving the links dynamically). And it would be a huge bonus if I could get an explanation on how to do it in JavaScript (using a library is fine). I am using AngularJS so how to apply it there would be even better.

Andreas
  • 2,450
  • 1
  • 18
  • 20
  • You should develop your links, you should add input fields to them and define the http method which they are using, not just the relation... So your client will be able to call your links even if it does not know anything about the link relation. I think it would be better with a standard/recommended media type, JSON-LD, HAL+JSON, etc... – inf3rno Mar 01 '14 at 18:35
  • @inf3rno Could you expand your answer? What do you mean by adding input fields to them? – Andreas Mar 01 '14 at 19:17
  • Here is an example: https://gist.github.com/mikekelly/5619934 In my vocabulary a link is an abstract controller trough you can communicate with you REST service. Its representation can be a HTML A element, a FORM element or even an XHR instance... – inf3rno Mar 01 '14 at 19:54
  • For example if you have a profile page and you want to get only the birthDay and the user name, then you should send the fields parameter in a queryString. `GET /users/1?fields="name,birthDay"`. The fields parameter can be filled by the service itself, or it can be filled by the client. The latter can be done when you describe the parameter, so you tell the client, that the `fields` parameter in this context can contain `id, name, birthDay, lastVisit, parents, friends, etc...` This type of information should be added to each link, which awaits params, if you want a decoupled client. – inf3rno Mar 01 '14 at 19:58
  • http://stackoverflow.com/a/20767057/607033 Here is another example for describing links with params. – inf3rno Mar 01 '14 at 20:04
  • @inf3rno How do you consume it in JavaScript like the scenario I described above? – Andreas Mar 01 '14 at 21:12
  • You how to choose the right link? Now that is a good question and depends on many things. If the client is user controlled, then the user should select the right link. If the client is automated, then you should teach it how to choose and follow links. There are many algorithms for that I think, but I am not an expert in this topic. There is an initiative, that we should define standards for how to describe certain things, for example the next page by paging a collection should have `next` link relation: http://www.iana.org/assignments/link-relations/link-relations.xhtml, etc... – inf3rno Mar 01 '14 at 21:34
  • Or for example [microdata](http://schema.org/) and [microformats](http://microformats.org/wiki/microformats2) define lots of different data types. If the client knows these link relations or data types, it can create a specific answer for them, for example it can display dates in a calendar instead of text format. Most of the hypermedia types are not prepared to add this kind of meta data to the responses, but for example JSON-LD is. – inf3rno Mar 01 '14 at 21:37
  • So writing automated clients is not a solved problem today... – inf3rno Mar 01 '14 at 21:38
  • Just try to google "linked data REST" and you will get many interesting articles... – inf3rno Mar 01 '14 at 21:40
  • If your question was about how to display the response of your REST API, that is not your concern, you won't write the REST clients... :-) Btw. it is pretty easy, you can generate concrete controllers and views from the abstract controllers and views you sent. For example by HTML your can create a HTML A tag from the GET links, etc... I don't know how angular works, but I guess you are able to create ViewModels from the json links you send. – inf3rno Mar 01 '14 at 21:44
  • Btw REST architecture is not so different from a classic HTTP client-server architecture. The only difference, that the REST responses should be machine understandable. HTML provided by the HTTP server is human understandable... It is slow to parse HTML understand its content and follow the right link... By REST it is much easier, you just have to teach your client to follow the link with the proper link relation. – inf3rno Mar 01 '14 at 21:48
  • @inf3rno Do you have time for chat? I got some more questions. – Andreas Mar 02 '14 at 17:13
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/48819/discussion-between-inf3rno-and-andreas) – inf3rno Mar 02 '14 at 21:17

2 Answers2

1

Angular-hateoas should do (most of) the job for you. However I agree with inf3rno and you should add the type to the links. So you may have to extend Angular-hateoas to handle it.

Pascal Le Merrer
  • 5,883
  • 20
  • 35
1

Yes, the client is supposed to navigate the links and retrieve whatever information it needs. There's nothing against you providing a summary resource that may have only some pieces of information needed, and the client retrieves the link for some relation when it needs more detail.

For instance, in HAL+JSON you have the _embedded property, in which you could embed a summary of the trainer, giving the bare minimum information needed about the trainer for the athlete's page.

Pedro Werneck
  • 40,902
  • 7
  • 64
  • 85
  • I have just read through the documentation of HAL and I am convinced that it is a good approach. I will adapt my web service and see how it turns out. – Andreas Mar 02 '14 at 01:03