Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to handle REST API paths when related resources belong to different microservices?

I have two microservices:

  • UserService, which defines paths such as /users, /users/:id;
  • MessageService, which defines paths such as /messages, /messages/:id.

Also, each message in MessageService has an attribute user_id which references a user in UserService.

Now, lets say I want to list all messages of a given user. Right now I can think of the following approaches:

  1. A path such as /users/:id/messages seems like the best approach if I want to follow the best REST API practices. However, it seems to me that I couldn't define such path inside MessageService because I would be tight-coupling it to UserService. I believe paths starting with /users should belong to UserService only.
  2. /messages?user_id=:id so I could use the existing /messages path and add a filter by attribute (user_id). Not sure if a good practice.
  3. Put an API gateway in front of the microservices and create a proxy from /users/:id/messages to /messages?user_id=:id. This allows clients to use the most REST-friendly path while keeping the microservices loosely coupled.

Which of these approaches would be the most appropriate?

like image 630
vitorsdcs Avatar asked Aug 10 '16 03:08

vitorsdcs


People also ask

Which URL pattern is recommended when working with one resources and a collection of resources?

Relative vs Absolute. It is strongly recommended that the URLs generated by the API should be absolute URLs. The reason is mostly for ease of use by the client, so that it never has to find out the correct base URI for a resource, which is needed to interpret a relative URL.

How do I secure API gateway in microservices?

Each consumer application should have a unique client ID, and based on the assumptions, APIs on the API gateway must be secured using OAuth 2.0. Once an application sends a request with an access token to the API gateway, the gateway can introspect the access token.

How do I merge microservices?

You need to write another service called Aggregator which will internally call both services and get the response and merge/filter them and return the desired result. This can be easily achieved in non-blocking using Mono/Flux in Spring Reactive. An API Gateway often does API composition.

Is API gateway mandatory for microservices?

If you don't have API Gateways, the client apps must send requests directly to the microservices and that raises problems, such as the following issues: Coupling: Without the API Gateway pattern, the client apps are coupled to the internal microservices.

How can we access RESTful in microservices?

The inventory microservice makes a request to the system microservice and stores the system property information. To fetch and store your system information, visit the http://localhost:9080/inventory/systems/localhost URL. You can also use the http://localhost:9080/inventory/systems/{your-hostname} URL.


2 Answers

There's no right or wrong answer for this question. IMO, it depends on whether messages are stand-alone resources or are part of a user resource in your domain logic.

If messages always belong to a single user, then you could view the user's messages as a sub-resource or a hierarchical division in the collection of messages and I would probably prefer the first URI scheme. In this case, I would probably go with a path like /user/:id/messages instead of the plural 'users'. Or put the user id behind the messages like: /messages/user/:id

If messages are an entity by themselves within your domain or can belong to multiple users (like email messages) it would make more sense to filter messages using a query string scheme.

like image 111
MvdD Avatar answered Sep 17 '22 16:09

MvdD


If you already designed your micro service where users and messages are two different domain/micro services, then your best bet will be designing a edge service that combines the two services and provide what client needs. For example, the service could be

/messages_by_user/:id

Remember a micro service will primarily provide CRUD operation on a domain resource, but client will need more than just CRUD operations on a resource and in that case you should always consider creating edge services to facilitate clients need.

If you haven't implemented the services yet then I would suggest putting both users and messages into the same micro service and consider user as a sub-resource of messages. In that case all the bellow paths are valid.

/messages
/messages/:id
/message/:id/users
/messages/user/:id

When you design a micro service, you need to strike the balance of what makes more sense. Although in theory every resource and their CRUD operation should have a separate micro service, but practically you can combine few related resources and make them a sub-resource as long as you are not compromising scalability, performance of the service.

like image 41
Sahidur Rahman Avatar answered Sep 18 '22 16:09

Sahidur Rahman