RESTful API:获取/设置一个没有id的“全局”单一资源

时间:2015-03-18 01:11:08

标签: api rest

TL; DR

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

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

从RESTful API访问全局 id 无状态的推荐方法是什么?

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

背景

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

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

示例:

// Backend
Context = "Poland"

然后

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

会回复:

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

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

// Backend
Context = "USA"

然后,相同的网址:

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

应该返回不同的数据集:

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

问题

由于上下文只是后端的全局状态,因此它没有 id 。它也不属于任何集合。不过,我希望它可以在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 )。资源名称是单数而不是复数

解决方案#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并且当然不能自我解释......而且,我有一个名字冲突:{{1} } vs id。资源名称是单数而不是复数

解决方案#3 - 行动

设置上下文

contextId

获取上下文

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

这与第一个非常相似,但是使用$ curl -X GET http://api.myapp.com/context/actions/get 可能是我整个API设计的一部分(取自gocardless。但是,我会遇到如何建模的问题很好地在前端方面。资源名称是单数而不是复数

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

谢谢!

2 个答案:

答案 0 :(得分:2)

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

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

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

答案 1 :(得分:1)

  

建议使用此全局无ID 状态的方法是什么   可以从RESTful API访问吗?

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

如果您希望您的API是RESTful,则必须在每次请求时传递此ID。