Question

We're designing and developing an enterprise application using Spring Boot for REST APIs and Angular 8 as the web client. It's been an year since we started.

When I started, I read multiple articles which cleared my understanding of why REST without HATEOAS is not actually REST. I went ahead with the then available Spring HATEOAS project which was on v0.25 (not stable) then but good enough to get us started.

Now, it has moved to a stable 1.x version and we have upgraded to it.

In our case, we have a collection of documents stored in MongoDB which is used for multiple APIs. Think of it as a collection which contains lot of information and it has more than 3 ways to represent. And 95% of our APIs are GET requests, only 5% are PUT, POST and DELETE. Its a monitoring application API, you get it.

Now, I believe that the relation between a Resource and a Controller should be one-to-one.

Question 1: Am I correct with this?

And,

Question 2: Am I correct with the premise that as soon as the URL is same, the resource structure must not change?

Like, every time I hit the URL https://example.com/status, I must get a consistent structure of Response, irrespective of the query params I give to the API i.e. the number of keys in the response will be the same, but the values could vary.

Question 3: How do we define parent-child relation in a resource. Or should we even care about it?

Moving on,

Question 4: If I want a subset of keys for a Resource, should I define a new Resource for it, or I can manipulate the structure by giving some query parameters?

Answer to even one of the question could help me a lot.

Was it helpful?

Solution

Resource and Controller should be one-to-one

There's no hard rule. That's the most common way to organize things, but other approaches might work as well or better depending on your system. As long as things are well organized in some way, it's fine.

As soon as the URL is the same, Resource structure must not change

URLs should uniquely identify a resource, but query parameters are part of the URL. /status?fields=foo is as much a separate resource from /status as /status/fields/foo is.

How do we define parent-child relation in a resource

That's what links are for. The "rel" in a link is short for "relation". So, make use of the tools Spring HATEOAS provides you to add links and include one for any related resource.

If I want a subset of keys for a Resource, should I define a new Resource for it, or I can manipulate the structure by giving some query parameters?

Remember that including query parameters makes it a separate resource. How you structure your URLs is an implementation detail that doesn't really matter. However, are you sure you need a trimmed down version of the resource? If your resource can be cached, getting the full version from the cache is going to be faster than making a request for the trimmed down version. If you have two different versions you might have to make two requests when one would have been sufficient.


One more bit of advice. To get the full value out of HATEOAS, you should be using a generic client to consume the API that understands the hypermedia your API responds with. If you're using Spring HATEOAS, you're probably using HAL. Here's an example of a HAL client https://github.com/badgateway/ketting.

OTHER TIPS

  1. This seems like a purely implementation question, it makes no difference to the end result but might make it easier to debug

  2. How would you explain to a client that sometimes a call returns X and sometimes Y? How would the client know which type to deserialise to? how would an application using the client know the return type of its call? It wouldnt be impossible, but it just makes things harder.

  3. Don't. This is documentation and you don't want to resend documentation with every request.

  4. Sending list parameters in URLs doesn't work very well and GetWhereIdInThisList type functions are awkward, but POSTing to RPC style paths status/getAllByParameterX is considered 'non RESTfull' You decide whether that means REST is inherently flawed or whether you can think up a crazy workaround.

Lots of good answers to other parts of this, but I think this important bit is misunderstood:

Question 2: Am I correct with the premise that as soon as the URL is same, the resource structure must not change?

Like, every time I hit the URL https://example.com/status, I must get a consistent structure of Response, irrespective of the query params I give to the API i.e. the number of keys in the response will be the same, but the values could vary.

No! The important part here is the request's Accept header.

The structure of the Response should certainly be different between Accept:image/png and Accept:application/json for reasons which I hope are not too obscure.

Licensed under: CC-BY-SA with attribution
scroll top