HATEOAS and microservices

1,086 views
Skip to first unread message

Andrew Braae

unread,
Nov 4, 2014, 3:13:40 PM11/4/14
to api-...@googlegroups.com
I have an API for getting widgets.

GET /widgets/{id}

My API lives in a microservices environment, meaning in my case that tenants can install additional microservices, which add new APIS.


For example there might be a widget branding microservices like this that allows color swatches to be stored against widgets:

GET /widgets/{id}/swatches

As the developer of the GET /widgets/{id} endpoint, I am unaware of the existence of the GET /widgets/{id}/swatches endpoint. It was built by someone else.


My question is about HATEOAS.

I don't see how I can (or should) usefully embed links inside my GET /widgets/{id} resource that help the caller understand that there is also a resource available for swatches.

I simply don't have that information - that API was built by someone else.

It seems like HATEOAS only has relevance within a single microservice, and some larger discovery mechanism (not HATEOAS as we know it) is needed to learn about all of the possible operations on a resource.

Is this a fair comment?

Pete Johanson

unread,
Nov 4, 2014, 3:30:20 PM11/4/14
to api-...@googlegroups.com

Obviously there is some extension point being used to let the tenant deploy the swatch endpoint. Why not add an additional extension point to the resource serving the widget endpoint that let's additional links be added?

Jørn Wildt

unread,
Nov 5, 2014, 2:41:57 AM11/5/14
to api-...@googlegroups.com
First off, I don't see how this changes HATEOAS as we know it - from the client side there is still hypermedia with links and other control elements. How these are generated is a server side implementation detail which has nothing to do with the client, REST or hypermedia on the outside of the API facade.

Second, as Pete said - its a matter of extension mechanisms. If you are using micro services then you are probably familiar with the term "Composite UI" - and you can do the same for a "Composite resource". That is, a resource which is pieced together by different API components from different micro services embedded in the resource handler. Its a matter of having extension points like "Here is a 'Widget' with ID X - who has relevant links for it?".

You can even do it on larger distributed "internet" scale using something like web hooks - whenever the Swatches service adds a Swatch to a Widget, it will do a callback to the Widget service to register the reference to the Swatch. Not you don't even need to embed pieces of code - everything is nice and RESTful based on HTTP :-)

/Jørn

On Tue, Nov 4, 2014 at 9:30 PM, Pete Johanson <lat...@gmail.com> wrote:

Obviously there is some extension point being used to let the tenant deploy the swatch endpoint. Why not add an additional extension point to the resource serving the widget endpoint that let's additional links be added?

--
You received this message because you are subscribed to the Google Groups "API Craft" group.
To unsubscribe from this group and stop receiving emails from it, send an email to api-craft+...@googlegroups.com.
Visit this group at http://groups.google.com/group/api-craft.
For more options, visit https://groups.google.com/d/optout.

Andrew Braae

unread,
Nov 5, 2014, 2:23:37 PM11/5/14
to api-...@googlegroups.com
Thanks for the input!

I understand its *possible* to synthesis a composite resource, so that the resource at /widgets/{} can contain hypermedia controls relating to to the whole wonderful world of related resources and actions for the widget in question (including swatches).

However I just don't know that its *desirable*, as it detracts from the simplicity of microservices, and creates couplings between APIs.

If for example /widgets/{} is produced on a server in Australia, and /widgets/{}/swatches on a server in Minnesota, then to use a composite approach, network traffic needs to flow from those places to wherever the composite is located, then from there to the client.

Whereas if the APIs remain unaware of each other, then the traffic flows directly from the client to the API endpoints, which is more resilient.

It just feels a tiny bit like pounding a square peg into a round hole to make HATEOAS cover all possible actions in a microservices architecture.

Pete Johanson

unread,
Nov 5, 2014, 2:39:28 PM11/5/14
to api-craft@googlegroups com

If each microservice is to have complete isolation at that level, perhaps you need an 'API root' per microservice, and the root can offer templated links to get the various widget resources, e.g. (HAL):

GET /
Host: swatchservice.myapi.com
{
  "_links": {
    "widget-swatch": {
      " href": "/widget/{id}/swatch",
      "templated ": true
    }
  }
}

That would let you have isolation, and at the same time give you most of the HATEOAS benefits.

If you needed a centralized facade, you could always compose all the API roots together for the centralized API root.

Kijana Woodard

unread,
Nov 5, 2014, 3:48:12 PM11/5/14
to api-...@googlegroups.com
The question would be, given {id} for "API A", how do you obtain the href for "API B".

At first glance, you'd have to "construct it in code" which is Not A Good Thing.

Personally, I think "something" has decided that these MicroServices, in fact, form one cohesive [macro?] service. The client isn't coordinating them, the micro services are working together on their own. That "something" should then be responsible for a coordinated representation.

Philip Nelson

unread,
Nov 5, 2014, 4:17:26 PM11/5/14
to api-...@googlegroups.com
Right, something has to have the macro sense? Building on what others here have said, could each service "register" it's root url, and agree on some rels it would provide, with the macro state machine service the client would use? Perhaps even register for a particular user. then the macro service calls only those services appropriately registered and builds the composite response. 


Andrew Braae

unread,
Nov 5, 2014, 5:30:32 PM11/5/14
to api-...@googlegroups.com
Yes, for us that something is the tenant (one of our customers), who has elected to installed apps A, B and C. So we know what their inventory, and we can certainly establish the superset of APIs they have.

Your answer has clarified to me that we're inferring a lot simply from URI templates.

As a client, I just infer that when I call GET /widgets/20/swatches, that will give me the swatches for the widget that lives at /widgets/20.

There's really no reason for me to assume that other than that the URI path parameter {id} is common to both /widgets/{id} and widgets/{id|/swatches. And the URIs look very similar.

With HATEOAS I could replace that inference with actual knowledge.

Thanks for all the input, this group is excellent.

Umang Singh

unread,
Mar 24, 2017, 12:54:36 AM3/24/17
to API Craft
Hi All,
I am new to the HATEOS world . I have a scenario where based on some parameters i can give certain options to the user and i also have a Microservice which takes the same parameter and tells the details for the product.

Microservice GET /{id}/features
Microservice GET /{id}/prodDetails

So in this scenario how can use HATEOS and provide links to resources from API to other. My intent is that i should be able to travel through resources .

In case of orchestration i know my resources so i can use my resource .

James Higginbotham

unread,
Mar 24, 2017, 11:29:30 AM3/24/17
to API Craft
Hi Andrew,

Funny, I was involved with a group discussion this week on the topic. Let me see if I can express my perspective to see if this helps.

In this situation, I might want to reconsider what a microservice is and how you expose it. Microservices are meant to be replaceable for experimentation without the need for creating reuse. APIs are meant to be stable for external consumption and seek reuse. There is nothing wrong with decomposing a system into microservices, but you should be exposing them via an external API rather than directly for such reasons as you have identified. That external experience API would be aware of the first microservice and could be updated as new microservice-based capabilities emerge. Therefore, the experience API would be able to formulate the appropriate links based on the rules of the system and availability of one or more microservices used to compose that external API. Of course, the hyperlinks would point to other experience-based APIs rather than the microservices directly, allowing for the "behind the scenes" aspects of your system to change while still providing the same contract to the external consumers. 

For further details, I have a slide deck from a previous talk that outlines how this looks: https://www.slideshare.net/launchany/applying-domain-driven-design-to-apis-and-microservices

James

Michael Tiller

unread,
Mar 25, 2017, 9:23:17 AM3/25/17
to api-...@googlegroups.com
Is this "id" something that only the user knows?  Or did they also get it via the API.

If it is something that only the user knows, think about this like a Google search.  Does the user type in a URL to find Google results?  No, they go to a page and they submit a POST request with the search term and they get back a set of links.  It is exactly the same in a hypermedia API.  You provide a link where they can post a payload (that includes the "id" in your case) and you return to them a payload that includes the links "features" and "product details".

If, instead, the "id" value came from the API then don't return an "id", return a URL to that resource instead.  Then the client can do a GET on that resource and get back the "features" and "product details" links from that.

The key in all cases is that YOU generate the links, not the clients (again, just as it is when browsing the web).

--
Mike

To unsubscribe from this group and stop receiving emails from it, send an email to api-craft+unsubscribe@googlegroups.com.
Visit this group at https://groups.google.com/group/api-craft.
Reply all
Reply to author
Forward
0 new messages