I will try to accumulate all my knowledge / experience about CRUD REST, will teach how to MAKE your API understandable and self-explainatory.
If you dont like reading just ENJOY THE PICTURES 🙂
Lets talk today about simple things
easy right? now to GET
event 99% of people would do this…
GET /event/{id}
{ "id": 1, "date": "2018-03-30T23:28:26.578Z", "type": "HACKATHON", "headline": "Alexey's lonely hackathon", "text": "Please someone come :(" }
this is OBVIOUS, and it’s cool because everybody will think this way – no need to explain what this api do.
Now if you call /event
without id what you will get?
GET /event
[ { "id": 1, "date": "2018-03-30T23:28:26.578Z", "type": "HACKATHON", "headline": "Alexey's lonely hackathon", "text": "Please someone come :(" }, { "id": 2, "date": "2018-03-30T23:28:26.578Z", "type": "SPORT", }, { "id": 3, "date": "2018-03-30T23:28:26.578Z", "type": "COFFEE_BREAK", "headline": "Sunshine coffee", "text": "Arabica + Robusta strong" } ]
if you didnt specify the {id}
this means id doesnt matter; this means you get a list of events (I think at least 50% would mean that)
Lets try POST
ing new event
POST /event
{ "type": "HACKATHON", "headline": "Elon Musk's hackathon", "text": "It's gonna be on Mars" }
4
{ "id": 4, "date": "2018-03-30T23:28:26.578Z", "type": "HACKATHON", "headline": "Elon Musk's hackathon", "text": "It's gonna be on Mars" }
we definitely need to send some data in this one, so how our request would look like? the most OBVIOUS body I can think of – same response that we got from GET /event/{id}
; so we’re using the same event json we got from server to actually create new one EXCEPT that there is no id in request (because event is new)
Also think of what we gonna get in response. Because you actually want to keep track of what you just created you need to return id of the created event. Or in some cases creation may affect initial request state – add some DEFAULT fields for example – so consider response_v2
example as an alternative (I think it’s better because it kindly added "date"
for us).
Updating event PUT
request looks like guess what? Of course the same as POST
request
POST /event
{ "id": 4, "text": "Actually lets do it on the Moon" }
{ "id": 4, "date": "2018-03-30T23:28:26.578Z", "type": "HACKATHON", "headline": "Elon Musk's hackathon", "text": "Actually lets do it on the Moon" }
But there are some catches, lets consider the following situations
- Probably our update affected other field like
lastUpdateDate
for example{ "id": 4, "text": "Actually lets do it on the Moon" }
{ "id": 4, "date": "2018-03-30T23:28:26.578Z", "lastUpdateDate": "2018-03-30T23:28:26.578Z", "type": "HACKATHON", "headline": "Elon Musk's hackathon", "text": "Actually lets do it on the Moon" }
to return an updated STATE of entire object is a good idea – better than just returning “OK” or “Done” or “id” as in
POST
example - What if there is a validation error? I would like to see smth like this
{ "id": 4, "text": "Actually lets do it on the Moon" }
{ "errorCode": 2, "errorMsg": "Sorry, nobody can mess with Elon Musk's events" }
First – you can make entirely different response structure if you’re using different HTTP response status – 400 Bad Request in this case suits very well for validation errors
As an alternative you can make the following base model for all your entities
in this case you’re always returning 200 but it contains information about “how the request actually went”{ "id": 4, "text": "Actually lets do it on the Moon" }
{ "result": { "successful": false, "errorCode": 2, "errorMsg": "Sorry, nobody can mess with Elon Musk's events" } }
{ "result": { "successful": true }, "data": { "id": 4, "date": "2018-03-30T23:28:26.578Z", "lastUpdateDate": "2018-03-30T23:28:26.578Z", "type": "HACKATHON", "headline": "Elon Musk's hackathon", "text": "Actually lets do it on the Moon" } }
i cannot say which approach is good or bad – you need to decide it yourself
How about deleting events? Seems easy
DELETE /event/{id}
4
(nothing just status 200)
{ "result": { "successful": true } }
Response may be different: id of deleted element, 200 status / 400 status with error, or Response
with result successful true / false
Summary
Today I told you about basic CRUD operations you can have with your entities, they are easy though as you may see, there are some options to choose:
GET /event/{id}
- request: no
- response: event with id={id}
GET /event
- request: no
- response: whole events list
POST /event
- request: event json (same as in
GET
but without id) - response: just an id / updated event json / validation error (400) or complex
Response
withResult
anddata
- request: event json (same as in
PUT /event
- request: event json (may be partial)
- response: updated event json / validation error (400) or complex
Response
withResult
anddata
DELETE /event/{id}
- request: no
- response: id of deleted event / status 200 / result object
PART 2 IS COMING SOON