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

TL;DR

In my current API, I've got two endpoints to handle the context:

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

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

Please assume that the context concept can't be changed .

Background

Let's say I've got a user that is logged. He's by default assigned to a context that he can change.

After the context change, all the subsequent API calls will return different data, according to the context.

Example:

// Backend
Context = "Poland"

then

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

will respond:

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

However, if you change the context:

// Backend
Context = "USA"

then, the same URL:

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

should return the different set of data:

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

Question

As the context is just a global state on the backend side, it doesn't have an id. It doesn't belong to any collection either. Still, I want it to be accessible in the API. There are three possible solutions I see:

Solution #1 - existing

Set a context

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

Get a context

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

This one doesn't really feel like a RESTful API and still, on the frontend side, I have to mock the id (using ember-data). And the resource name is singular instead of plural.

Solution #2 - mocking the id

Set a context

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

Get a context

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

Here I mock the id to always equal to one but I feel that it's super hacky and certainly not self-explanatory... Moreover, I've got a name conflict: id vs contextId . And the resource name is singular instead of plural.

Solution #3 - actions

Set a context

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

Get a context

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

This is very similar to the first one but using actions that could be a part of my whole API design (taken from eg gocardless. Still, I'll have a problem how to model it on the frontend side nicely. And the resource name is singular instead of plural again.

Is there any #4 option? How should I address this problem?

Thanks!


Your three solutions are RPC, not REST. Not only they are not stateless, but setting a resource to some other resource by setting an id is very RCP'ish.

A RESTful solution, if you really want to go that way, is to set the context in a header. The client should send a header like X-ContextId or something like that, and you determine the request context you need from that.

However, don't worry too much about being RESTful if that's not what your application requires. I recommend reading the answer here: SOAP vs REST (differences)


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

A RESTful API is by definition stateless , no client context should be stored on the server between requests.

If you want your API to be RESTful, you'll have to pass this id with each request.

链接地址: http://www.djcxy.com/p/71482.html

上一篇: JSON RESTful Web服务应使用数据合同

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