I'm new to REST API, so I decided to get familiar with it by designing a small web service API. I have its design written down and would like you to review it. I feel like I have made some mistakes in designing it and understanding REST concepts, which I try to address with questions on my design at the very end. I'm mostly unsure about my use of URLs for the API.
The web service I try to design provides a way for a user to store key=value pairs, i.e. retrieve value knowing its key, update the value of an existing key and delete an existing key. The whole CRUD set of actions!
Here is what I have came up with.
Versioning
Since my API might evolve, I want a notion of API versions, so I have
GET api.example.com/supported-versions
Which returns a JSON list of integers denoting the API versions supported.
The API will be available at api.example.com/{VERSION}/
endpoint, e.g. api.example.com/1/
for the first version.
Key=value storage
GET api.exmaple.com/1/keys/{KEY}
Allows a user to get a value associated with a key KEY
. The server responds with a status code (200, 404, etc.) and a text value on success, both encoded in JSON.
POST and PUT api.exmaple.com/1/keys/{KEY}?value={VALUE}
Allows a user to create/update the value associated with the key KEY
. The server returns a status code (200, 404, etc.). VALUE
is a text string.
DELETE api.exmaple.com/1/keys/{KEY}
Allows a user to delete a key=value pair with key KEY
. The server Which will delete the key=value pair and return a status code (200, 404, etc.).
Let's imagine that there is an OAuth2 authentication set up, which is used for the up above POST/PUT/DELETE methods (but not GET anyone can GET, you don't need authentication for that), so there is a way to uniquely identify a user and keep track which key=value pairs belong to which user.
Now, I want an authenticated user to be able to get a list of all keys they have, so that they don't have to store this information on client-side in order to send DELETE or PUT request later.
GET api.exmaple.com/1/keys?page={PAGE}
This allows a user to get a list of all existing keys they have created. PAGE
is an optional parameter. User can increase page count until the user gets an error status code. It returns a paged list of all existing keys a user have created and also a status code (200, 404, etc.).
Is there anything wrong with this API?
Should the first GET/POST/PUT/DELETE from Key=value storage section be on /keys/
or /values/
?
Is it fine that the last "GET", the one which returns all keys a user has, is also /keys/
?
Best Answer
Your solution is OK, save for a few things:
Versioning REST APIs at the resource level is generally not a good practice, although this not necessarily a consensus view. See here for some comments and links to further discussion.
To your second question, you could probably argue either way as to whether
/keys/{id}/
or/values/{id}/
is correct, but my instinct would be to either usekeys
since it's the "parent" of the tuple, or I'd use an entirely different name such as/data/
or/elements/
, or whatever it is these things actually represent.I would probably have different GET methods for the whole key-value dictionary, e.g.
/keys/{id}
/, and a separate resource for those for a particular user, e.g./users/{id}/keys/{keyId}
.Finally, it's not great (although possible) to use query strings with POST/PUT/DELETE methods. It is a query string, after all. Instead, you could use POST
/data/
, and put the key-value pair as JSON data in the request body. See this question as well.