RESTful API: get/set 一个 "global" 没有 id 的单个资源

RESTful API: get/set one "global" single resource without id

TL;DR

在我当前的 API 中,我有两个端点来处理上下文:

GET /context/get
POST /context/set '{"id": "123"}'

让这个 globalid 无状态可从 RESTful API 访问的推荐方法是什么?

请假设上下文概念无法更改

背景

假设我有一个已登录的用户。他默认分配到他可以更改的 上下文

上下文更改后,所有后续 API 调用将根据上下文 return 不同的数据。

示例:

// Backend
Context = "Poland"

然后

$ curl -X GET http://api.myapp.com/cities

将回复:

{
  "cities": [{
    "id": "1",
    "name": Warszawa"
  }, {
    "id": "2",
    "name": Wrocław"
  }]
}

但是,如果您更改上下文:

// Backend
Context = "USA"

那么,一样 URL:

$ curl -X GET http://api.myapp.com/cities

应该return不同的数据集:

{
  "cities": [{
    "id": "3",
    "name": New York City"
  }, {
    "id": "4",
    "name": Boston"
  }]
}

问题

由于 context 只是后端的 global state,它没有 id 。它也不属于任何 collection。不过,我希望它可以在 API 中访问。我看到三种可能的解决方案:

解决方案 #1 - 现有

设置上下文

$ curl -X POST http://api.myapp.com/context/set '{"id": "123"}'

获取上下文

$ curl -X GET http://api.myapp.com/context/get

这个感觉不像 RESTful API 而且,在前端,我必须模拟 id(使用 ember-data )。并且资源名称是 singular 而不是 plural.

解决方案 #2 - 模拟 id

设置上下文

$ curl -X POST http://api.myapp.com/context/1 '{"contextId": "123"}'

获取上下文

$ curl -X GET http://api.myapp.com/context/1

在这里,我将 id 模拟为始终等于 1,但我觉得它超级 hacky 而不是 self-explanatory...此外,我有一个名称冲突:idcontextId。并且资源名称是 singular 而不是 plural.

解决方案 #3 - 操作

设置上下文

$ curl -X POST http://api.myapp.com/context/actions/set '{"id": "123"}'

获取上下文

$ curl -X GET http://api.myapp.com/context/actions/get

这与第一个非常相似,但使用的 actions 可能是我整个 API 设计的一部分(取自例如 gocardless。不过,我会有如何在前端很好地建模它的问题。资源名称是 singular 而不是 plural 再次。

有#4选项吗?我该如何解决这个问题?

谢谢!

What's the recommended way of having this global, id-less state accessible from RESTful API?

A RESTful API 是 by definition 无状态,请求之间不应在服务器上存储客户端上下文。

如果您希望 API 成为 RESTful,则必须在每个请求中传递此 ID。

你的三个方案都是RPC,不是REST。不仅它们不是无状态的,而且通过设置 id 将资源设置为其他资源非常 RCP'ish。

一个 RESTful 解决方案,如果你真的想那样做,就是在 header 中设置上下文。客户端应该发送 header 之类的 X-ContextId 或类似的东西,然后您从中确定所需的请求上下文。

但是,如果这不是您的应用程序所需要的,请不要太担心成为 RESTful。我建议在这里阅读答案:SOAP vs REST (differences)