REST in simple words.

Basics.

REST is a communication pattern designed to provide interoperability between different web-services. Heavily used in the modern client-server apps and modern websites based on API-first approach: Angular, React, others.The central point of REST is the term “resource”, then term “operations” goes. 
So, you have a set of resources and then each of this “resources” has a set of “operations” that client allowed to perform.

Then the term “methods” go, we have a limited set of them in REST.

Making the story short:
GET — used for getting the data from the server.
POST — for creating new instances.
PUT/PATCH — for modifying the existing data in the system.
DELETE — used if you need to delete the instance from the system.
OPTIONS — to get the list of available methods for the resource.
HEAD — used to determine if a resource is available.

OPTIONS & HEAD methods commonly unused.

If we summarize all the written above, in our toolbox we will have Resources and operations to be done with the methods.

Managing resources

Thinking from the perspective that REST have limited set of methods and operations are also limited, so.. that leads us to idea that we can unify all operations in our web-service, reduce the amount of code to be written, standardization! So we can do things faster, we have way more flexible and maintainable backend. The app becomes totally model-driven, design the models and rules more, that means that unit testing could be also done as abstraction and can be dynamic. Adding abstractions and base classes to communication level allows to minimize codebase significantly.

Here is the how “book” resource may look like for the book table that represents the book model in your app.

GET: /book/— get collection of books. 
GET: /book/{1} — a single book
POST: /book/ — create new book.
PUT/PATCH: /book/{id} — modify existing book with {id}.
DELETE: /book/{id} — delete book with {id} from the system.

Once the request was sent to a server from a client, servers should reply with an answer and the status code. If there were no error we send — “200” as a status code, the response body is empty. No need to send {success:”new resource created”}, please. Its already clear by 200 value.

Success: 2xx status used as a success code for all types of operations: Create/Read/Update/Delete. So we have something similar to CRUD pattern from MVC.

Error: In a case of a problem or an error on the side of backend, we send one of status codes from HTTP list starting with 4xx or 5xx. If it’s not enough, only then we add basic messages like {“Unable to create a resource”}. Later you will be able to add needed standardization for an error message, based on the pattern you would like the most.

This approach could be applied to 90+% of models. Apps are based on tables or collections(NoSql) = they are models. Models = Resources.

Tricky parts of POST

POST request is used to create a new resource, each time we send POST a new resource will be created. Newly created resource could be found by accessing the value of location header, see 10.2.2 201 section of https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html

And the example of request/response looks this way:

Request
Method: POST
Payload: {title:"BookA", description:{"lorem ipsum dolor"}}
URL: /book/
Response
StatusCode: 201
Location Header: /book/1

Sometimes response 201 is not enough, and you need to have to full data of your model for the response, this case you need to send one request more to access the data of the newly created model. That is ok.

But if you want to skip getting data by accessing GET: /book/1, you may do it its allowed. I don’t like this idea, but “they” used word SHOULD in the specification, so it’s allowed.

The response SHOULD include an entity containing a list of resource characteristics and location(s) from which the user or user agent can choose the one most appropriate.

So the response will have the content body inside with all required data.

Request
Method: POST
Payload: {"title":"BookA", "description":"lorem ipsum dolor"}
URL: /book/
Response
StatusCode: 201
Body: {"Id":1, "UserId":1, "title":"BookA", "description":"lorem ipsum dolor"}

PUT vs PATCH

Now we need to update the resources(the data of models), for this case PUT and PATCH are used. Making big small again, use PUT if you send whole data of your object. PATCH for the cases when you want to update a part of the resource. So its more up to and the way you design your update operations.

Available successful codes for the PUT are 200,204.

Request
Method: PUT
Payload: {"id":1, "title":"BookA", "description":"new description"}
URL: /book/1
Response
StatusCode: 204

Get

The rule: GET is used for all cases when you are not modifying the state of the resource. Simply for accessing the data, just for this. Using GET for other purposes is a mistake.

Getting a collection:

Request
Method: GET
Payload: {limit:10, offset:40}
URL: /book/
Response
StatusCode: 200
Body: [{"id":"51","title":"Book5A"},{"id":"52","title":"Book5B"},...]

Getting a single item:

Request
Method: GET
Payload: {limit:10, offset:40}
URL: /book/51
Response
StatusCode: 200
Body: {"Id":1, "UserId":1, "title":"BookA", "description":"lorem ipsum dolor"}

Delete

The name talks by itself, when you need to remove an item or undo an operation that you’ve made to a resource. Remove a book for example, or if you’ve make book “liked”, then for “unlike” operation DELETE method should be used.

Removing the “like” from the book

Request
Method: DELETE
URL: /book/51/unlike
Response
StatusCode: 200

Swagger

At the time when your API goes big — Swagger is MUST. Its a software for API documentation, testing, exposing. No need to make any manually written pages, please.

Idea in nutshell — you provide metadata(description) for you API methods, pass this metadata to swagger as input, as output you will have web-page running with all your methods inside + tool to test your API..

All popular frameworks have swagger integration(+1 to automation).

Idempotent and Save

A method that gives the same outcome each time you send the same query is Idempotent. Methods which do not modify the resources is Safe.

https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html