0

寻找有关 REST API 架构设计的一些输入。我经常发现所需的数据是跨多个资源的视图的组合。您希望客户端将它们组合起来,还是提供一个 API 来为客户端进行组合?

例如,假设我们正在编写一个 REST API,以便人们收到有关事件的通知。有人会通过以下两种方式之一表示对事件的兴趣:

  • 加入一个定期举办人们感兴趣的活动的组织
  • 搜索并标记由我通常不会订阅的组织运行的特定事件

100我可以通过执行以下长步骤为用户检索所有事件:

  1. GET /user/100/organizations返回123
  2. GET /organizations/123/events返回[15,16,20]
  3. GET /user/100/savedevents返回[35,36]
  4. GET /events/15,16,20,35,36返回所有事件

但这对客户来说似乎相当沉重。我几乎希望客户能够说,“给我这个用​​户的所有有趣事件”:

GET /user/100/events

...然后要求服务器了解它必须经过所有步骤 1-4 并返回它们,或者至少返回,[15,16,20,35,36]因此它变成 2 个步骤:获取事件 ID;获取活动详情。

这是否有意义,以这种方式创建一个跨越多个资源的视图?

编辑:进一步解释。我犹豫是因为我可以看到/organizations/123/events干净的资源如何;if 等同于说/events?organizations=123,即“给我组织=123 的资源事件”。对/user/100/organizations.

/user/100/events不是“给组织 = 123 的资源事件”。它是“给我用户 = 100 的组织注册,检索那些组织 ID,然后给我组织 = 123 的事件,然后给我保存用户 = 100 的事件。”

这三个步骤中的每一个本身都是一个干净的资源映射。把它们放在一起似乎很乱。但是要求客户端(尤其是 Web 客户端)弄清楚所有这些逻辑也是如此!

4

2 回答 2

2

我对你的问题有点困惑,所以我会尽可能全面,希望我能找到你需要的答案=P。

我经常发现所需的数据是跨多个资源的视图的组合。您希望客户端将它们组合起来,还是提供一个 API 来为客户端进行组合?

在真正的 RESTful 环境中,数据的所有横截面视图都将由服务器完成,而不是由客户端完成。

RESTful 设计的主要原因是允许通过使用标准 HTTP 动词(例如、、、、)访问 CRUD 模型(创建读取更新删除)。将这些方法的返回存储在某种会话或 cookie 或其他外部方法中(例如,“给我 bob 的数据”、“给我关于企业的数据”、“给我前两个查询的数据”)超越了REST 方法论。 GETPOSTPUTDELETE

您希望利用 RESTful 开发的方式是找到以有意义的方式组合资源的方法,以便提供方法调用一致的 RESTful 环境;GET读取数据、POST创建数据、PUT更新数据、DELETE删除数据)。

因此,如果您想执行步骤 1 到 4 之类的操作,我建议您执行以下操作:

GET /user/{userID}/organizations --> {return all affiliated organizations}
GET /user/{userID}/events --> {return all events associated with userID}
GET /organizations/{organization}/events --> {returns all eventID's assoc. with organization}
GET /user/{userID}/savedevents -->  {return all eventID's userID saved to their profile}
GET /events/?eventID=(15,16,20,35,36) --> {return all of the events details for those eventID's}
GET /events/{eventID}--> {return events details for {eventID}}

而您可能还有:

GET /events/  --> {return a complete listing of all event ID's}
GET /events/{userID}  -->  {return all events userID is associated with}
POST /event/  --> {create a new event - ID is assigned by the server}
POST /user/   --> {create a new user - ID is assigned by the server}
PUT /user/{userID}  --> {update/modify user information}

然后,如果您想要横截面的信息切片,您将拥有横截面的命名资源(否则将其作为参数传递)。明确使用您的资源(随机仅供参考,仅将您的资源命名为名词 - 而不是动词)。

你还问:

进一步解释。我犹豫是因为我可以看到 /organizations/123/events 是一个干净的资源;if 等同于说/events?organizations=123,即“给我组织=123 的资源事件”。/user/100/organizations 也一样。

本质上,named resourcedresource + argument方法都可以提供相同的信息。通常,我只在需要重要描述(范围请求、日期请求、一些非常小的数据单元等)时才看到 RESTful 设计 API 调用参数。如果您有一些可以进一步解析/自省的高阶数据分组,那么它就是一个命名资源。在您的示例中,我将同时使用 API 调用,因为 RESTful 规范要求通过多个路径和使用已建立的 HTTP 方法提供数据。不过,我也想扩大一点......

/events?organizations=123 -->  {return the eventID's associated with org=123}
/organizations/123/events  -->  {return event DETAILS for events associated with org=123}

阅读/阅读此内容,作者:Apigee

于 2013-10-06T13:53:42.237 回答
0

可能有几种方法可以解决这个问题......但是,我认为大多数时候(如果服务由同一提供者管理)最好在服务器端拥有逻辑并使 REST 调用与彼此可能(即服务器执行所需的多个操作 - 通常从存储在 API 资源中处理的数据的 DB 中读取数据)。

在您谈论的示例中,这意味着您的 REST API 将公开他感兴趣的“用户”资源和子资源“事件”(您称之为“保存的事件”)。考虑到这一点,您将拥有类似这样的东西:

  • POST /user/{username}/events存储用户感兴趣的新事件(或多个事件)
  • GET /user/{username}/events返回用户感兴趣的所有事件
  • GET /user/{username}/events/{eventid}返回特定事件的详细信息

要“过滤”每个组织的用户事件(和其他过滤操作),您可以使用“查询参数”:

  • GET /user/{username}/events?organization=123

因此,服务器(或 API 调用)将执行您在GET /user/{username}/events. 您仍然可以在 API 中创建其他资源(“组织”和“事件”),但是它们将在其他上下文中使用(例如存储新事件或组织等)。

高温高压

于 2013-10-06T13:18:35.450 回答