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