当相关资源属于不同的微服务时,如何处理REST API路径?

时间:2016-08-10 03:39:49

标签: rest microservices

我有两个微服务:

  • UserService,定义路径,例如/ users,/ users /:id;
  • MessageService,定义路径,例如/ messages,/ messages /:id。

此外,MessageService中的每条消息都有一个属性user_id,它引用UserService中的用户。

现在,假设我要列出给定用户的所有消息。现在我可以想到以下方法:

  1. 如果我想遵循最佳REST API实践,那么 / users /:id / messages 之类的路径似乎是最好的方法。但是,在我看来,我无法在MessageService中定义这样的路径,因为我会将它紧密耦合到UserService。我认为以/ users开头的路径应该只属于UserService。
  2. / messages?user_id =:id 所以我可以使用现有的/ messages路径并按属性(user_id)添加过滤器。不确定是否是一个好的做法。
  3. 在微服务前放置一个API网关,并从 / users /:id / messages 创建一个代理到 / messages?user_id =:id 。这允许客户端使用最友好的REST路径,同时保持微服务松散耦合。
  4. 哪种方法最合适?

2 个答案:

答案 0 :(得分:3)

这个问题没有正确或错误的答案。 IMO,它取决于消息是独立资源还是域逻辑中用户资源的一部分。

如果消息总是属于单个用户,那么您可以将用户的消息视为消息集合中的子资源或分层划分,我可能更喜欢第一个URI方案。在这种情况下,我可能会使用类似/user/:id/messages的路径而不是复数“用户”。或者将用户ID放在消息之后:/messages/user/:id

如果邮件在您的域中是一个实体,或者可以属于多个用户(如电子邮件),那么使用查询字符串方案过滤邮件会更有意义。

答案 1 :(得分:3)

如果您已经设计了微服务,其中用户和消息是两种不同的域/微服务,那么您最好的选择是设计一种边缘服务,将两种服务结合起来并提供客户需求。例如,服务可能是

/messages_by_user/:id

请记住,微服务主要在域资源上提供CRUD操作,但客户端需要的不仅仅是资源上的CRUD操作,在这种情况下,您应该始终考虑创建边缘服务以方便客户端。< / p>

如果您还没有实现这些服务,那么我建议将用户和消息都放在同一个微服务中,并将用户视为消息的子资源。在这种情况下,所有波纹管路径都是有效的。

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

当您设计微服务时,您需要在更有意义的方面取得平衡。虽然理论上每个资源及其CRUD操作都应该有一个单独的微服务,但实际上只要不损害服务的可伸缩性和性能,就可以将很少的相关资源组合起来并使它们成为子资源。 / p>