source/_posts/2013-10-06-a-quick-look-at-rest.markdown
76abe111
 ---
 layout: post
 title: "A quick look at REST"
 date: 2013-10-06 14:27
 comments: true
 categories: [server, shell, webdev]
 cover: /images/cover/avatar.png
 keywords: rest, restful, Representational State Transfer, crud, api, post, get, put, delete
 description: An intro to REST
 ---
 
 Three months ago I've chosen a 
 [REST](http://en.wikipedia.org/wiki/Representational_state_transfer) 
 architecture for designing my new project at work. The project goal is to create 
 <abbr title="Application Programming Interface">API</abbr> for managing gyms, 
 trainings and trainees. 
 
 This article is just light intro to the REST world, don't expect cool tips & 
 tricks (maybe in next article).
 
 # HTTP request methods
 
 REST without using proper [HTTP methods](http://en.wikipedia.org/wiki/
 Hypertext_Transfer_Protocol#Request_methods) is a nonsense. There are about 9 
 methods but we need only 4.
 
 * ```POST``` -- create a new resource
 * ```GET``` -- get resource data
 * ```PUT``` -- update a resource
 * ```DELETE``` -- delete a resource
 
 There is also ```PATCH``` method which is very similar to ```PUT``` method.
 In fact ```PUT``` should rewrite a whole resource and ```PATCH``` only update 
 some attributes of a resource. More about ```PUT``` vs ```PATCH```
 [here](https://restful-api-design.readthedocs.org/en/latest/methods.html#patch-
 vs-put).
 
 <!-- more -->
 
 # Simple example (we always work with objects)
 
 REST greatly improves a simplicity of using the API. Let's have a look at an 
 example how we manage trainings:
 
 	http://api.example.com/training/
 	http://api.example.com/training/:training/
 
 We can access that URLs via ```GET```, ```POST```, ```PUT``` or ```DELETE``` 
 HTTP methods. If we want 
 to create a new training then we call the first URL. If we want to read 
 training data, or update data, or delete a training then we use the second URL 
 (just replace ```:training``` with some integer). Actually, REST force you take 
 an advantage of 
 [CRUD](http://en.wikipedia.org/wiki/Create,_read,_update_and_delete). And 
 that's good. As you can see, to make operations with trainings we need just two 
 URLs (I call them *access points*).
 
 The philosophy of REST is to access *objects*. In the example ```training``` 
 was the object. The reason is simple -- we can make CRUD operations (read, 
 write, update, delete) only with objects.
 
 # Another example
 
 Well, you can ask: "What if I need to tell a trainee X wants to join training 
 Y?". I solved the problem by creating another access point:
 
 	http://api.example.com/training/:training/attendance/:trainee/
 
 Now we are working with ```attendance``` object. Allowed HTTP methods for this 
 access point are PUT and DELETE. 
 If a trainee with ID 541 wants to join training with ID 1050 we call 
 ```http://api.example.com/training/1050/attendance/541/``` with ```PUT``` 
 method. Later the trainee changes his mind and wants to leave the training, so 
 we call the same URL with ```DELETE``` method.
 
 # How to send data to server with cURL
 
 I'll illustrate using REST API with curl utility.
 
 ## POST method:
  
 Let's create a new training:
 
 {% codeblock lang:bash %}
 	curl -X POST \
 		--data-urlencode "starts_at=2013-12-12 12:00" \
 		--data-urlencode "ends_at=2013-12-12 13:00" \
 		--data-urlencode "name=New training" \
 		http://api.example.com/training/
 {% endcodeblock %}
 
 A simplified server response can look like this (in JSON):
 
 {% codeblock lang:json %}
 {
 	"id"             : 800,
 	"name"           : "New training",
 	"starts_at"      : "2013-12-12T12:00:00+0100",
 	"ends_at"        : "2013-12-12T13:00:00+0100",
 	"created_at"     : "2013-10-06T17:23:12+0200",
 	"updated_at"     : "2013-10-06T17:23:12+0200"
 }
 {% endcodeblock %}
 
 ## GET method:
  
 Now we know training ID. Getting information about training:
 
 {% codeblock lang:bash %}
 	curl http://api.example.com/training/123/
 {% endcodeblock %}
 
 We haven't changed training data so a server response looks exactly like in 
 above example.
 
 ## PUT method:
  
 I made a mistake! The training should ends at 13:30, let's change it:
  
 {% codeblock lang:bash %} 
 	curl -X PUT \
 		--data-urlencode "ends_at=2013-12-12 13:30" \
 		http://api.example.com/training/800/
 {% endcodeblock %}
 
 A simplified server response:
 
 {% codeblock lang:json %}
 {
 	"id"             : 800,
 	"name"           : "New training",
 	"starts_at"      : "2013-12-12T12:00:00+0100",
 	"ends_at"        : "2013-12-12T13:30:00+0100",
 	"created_at"     : "2013-10-06T17:23:12+0200",
 	"updated_at"     : "2013-10-06T17:32:11+0200"
 }
 {% endcodeblock %}
 
 ## DELETE method:
 
 This deletes training:
 
 {% codeblock lang:bash %}
 	curl -X DELETE \
 		http://api.example.com/training/800/
 {% endcodeblock %}
 
 An obligatory server response:
 
 {% codeblock lang:json %}
 {
 	"success" : true
 }
 {% endcodeblock %}