HATEOAS client with AngularJS
Asked Answered
A

5

31

I was wondering if there were any features hidden in Angular or exposed by some 3rd-party libraries to easily create HATEOAS-compliant Restful clients.

On backend side, I am using Spring Data/REST to produce an HATEOAS JSON API. Consuming it, though, is quite another story.

For instance, I've got those 3 entities:

  • Company {name, address}
  • Employee {firstName, lastName, employer[Company]}
  • Activity {rate, day, employee[Employee], client[Company]}

and requesting an activity (the most complex entity of the model) produces something like this:

{
    links: [],
    content: [{
            rate: 456,
            day: 1366754400000,
            links: [{
                rel: "self",
                href: "http://localhost:8080/api/activities/1"
            },
            {
                rel: "activities.activity.client",
                href: "http://localhost:8080/api/activities/1/client"
            },
            {
                rel: "activities.activity.employee",
                href: "http://localhost:8080/api/activities/1/employee"
            }]
        }]
}

My API talks in terms of REST (resources identified by links). An Activity has an Employee for instance. What I really want to use is : {rate: 456, day: 1366754400000, employee: {firstName:"xxx", lastName:"xxx" ...}}.

However, as you can see in the first output, my Activity only contains a link to the employee, not its data. Is there anything in Angular or in a 3rd-party library to resolve those links and embed the resulting data instead?

Any input on this?

Thanks in advance!

Andesite answered 21/4, 2013 at 1:42 Comment(6)
any features hidden in Angular...what features have you tried that weren't able to do what you want? There are numerous ways within angular to present your data. It's really not clear what your issue is. Your last sentence is very hard to understand. Please explain in more detailFeltner
Hi, I edited the last sentence, I hope it's clearer. What I basically mean is: on client side, I don't wanna work with links but with the data directly.Andesite
create a service that will set up the links , that's simple. You know how to create a service ? then you know how to search through a json file for a link and request something according the link. It's like loading a configuration file from a service. after the config is available , just set up the service properly.Vociferate
Creating an Angular service, yes, I can do that. But I'm not sure how to efficiently implement the logic to follow links and resolve them.Andesite
do you control the REST? If so why does it output links and not data when requesting employee. Other wise you will have to make a request to that url to get the data. Still not very clear what problem is. Explanation is not very preciseFeltner
This is the default Spring Data/REST output, which takes no time to produce (tweaking it does). If we follow HATEOAS logic (AFAIK), a compliant API should expose links and the client should follow those links. It's not so easy as just doing one more request. For instance, in case of an activity, I must make: * 1 extra request to fetch an employee (+ 1 extra request to fetch his/her employer) * 1 extra request to fetch the client And this is only because my domain is simplistic and has got only 3 entities. Is there any JS client lib following HATEOAS constraints (link resolution etc)?Andesite
A
20

Checkout angular-hateoas. ITs an AngularJS module for using $resource with a HATEOAS-enabled REST API.

Alex answered 1/4, 2014 at 2:18 Comment(2)
Cool, it looks very similar to Restangular (API-wise).Andesite
And it really embeds the notion of following links, contrary to Restangular, which is very cool!Andesite
R
7

You could write a Response Transformation that would inspect your returned object, check for links, and resolve them before returning the response. See the section "Transforming Requests and Responses" in the $http service documentation.

Something like this:

transformResponse: function(rawData) {
  var json = JSON.parse( rawData );
  forEach( json.content.links, function(link) {
    // resolve link...
  });
  return json;
}

Since the "resolve link" step is itself an $http call, sub-references would also be resolved. HOWEVER, since these are asynchronous, you would likely return a promise instead of the real value; I don't know if the transform function is allowed to do this.

As @charlietfl pointed out, however, please note that this will result in several HTTP calls to return a single entity. Even though I like the concept of HATEOAS, this will likely result in sluggishness if too many calls are made. I'd suggest that your server return the data, or some of it, directly, PLUS the link for details.

Rainmaker answered 22/4, 2013 at 6:49 Comment(0)
N
2

Based on your comment about wanting to work with data as against links on the client, I think Restangular would be a good fit.

Nonsense answered 30/7, 2013 at 19:59 Comment(2)
As for now in 2014 I'm also thinking a bit about what would be the best fit in the AngularJS ecosphere for HATEOAS-style consuming. So how did it end, @Rolf?Kaffraria
Well, I did not investigate enough on the issue. Restangular allows consuming an API over HTTP (may it be RESTful or not) very easily. No automatic discovery (based on HATEOAS) though.Andesite
S
2

I've been using angular-hal for one of my projects. It was a Spring HATEOAS backend. And I didn't run into any issues. It handles parametrized resources. I suspect it only supports HAL so since you're using Spring Data Rest you probably have to configure it to generate HAL compliant responses.

Selina answered 16/10, 2014 at 23:15 Comment(1)
P
0

I think the confusion may be that you are asking for an Angular solution, when what you really want to do is have Spring Data send a more complete JSON response. I.e, you really just want the server to return the employee data as part of the response JSON, rather than having the client perform extra steps to look it up. I don't know what data store you are using in Spring Data, but the general solution would be to add public getEmployee() method to your Activity class and then annotate the method with @RelatedTo and @Fetch (this would be the setup for Neo4J -- may be different annotations for your flavor of Spring Data). This should cause Spring HATEOAS to include the Employee record within the response for /activity. Hope this helps.

Panek answered 16/10, 2015 at 12:4 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.