Browse code

New article about REST

Cinan Rakosnik authored on 06/10/2013 at 16:07:45
Showing 1 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,154 @@
0
+---
1
+layout: post
2
+title: "A quick look at REST"
3
+date: 2013-10-06 14:27
4
+comments: true
5
+categories: [server, shell, webdev]
6
+cover: /images/cover/avatar.png
7
+keywords: rest, restful, Representational State Transfer, crud, api, post, get, put, delete
8
+description: An intro to REST
9
+---
10
+
11
+Three months ago I've chosen a 
12
+[REST](http://en.wikipedia.org/wiki/Representational_state_transfer) 
13
+architecture for designing my new project at work. The project goal is to create 
14
+<abbr title="Application Programming Interface">API</abbr> for managing gyms, 
15
+trainings and trainees. 
16
+
17
+This article is just light intro to the REST world, don't expect cool tips & 
18
+tricks (maybe in next article).
19
+
20
+# HTTP request methods
21
+
22
+REST without using proper [HTTP methods](http://en.wikipedia.org/wiki/
23
+Hypertext_Transfer_Protocol#Request_methods) is a nonsense. There are about 9 
24
+methods but we need only 4.
25
+
26
+* ```POST``` -- create a new resource
27
+* ```GET``` -- get resource data
28
+* ```PUT``` -- update a resource
29
+* ```DELETE``` -- delete a resource
30
+
31
+There is also ```PATCH``` method which is very similar to ```PUT``` method.
32
+In fact ```PUT``` should rewrite a whole resource and ```PATCH``` only update 
33
+some attributes of a resource. More about ```PUT``` vs ```PATCH```
34
+[here](https://restful-api-design.readthedocs.org/en/latest/methods.html#patch-
35
+vs-put).
36
+
37
+<!-- more -->
38
+
39
+# Simple example (we always work with objects)
40
+
41
+REST greatly improves a simplicity of using the API. Let's have a look at an 
42
+example how we manage trainings:
43
+
44
+	http://api.example.com/training/
45
+	http://api.example.com/training/:training/
46
+
47
+We can access that URLs via ```GET```, ```POST```, ```PUT``` or ```DELETE``` 
48
+HTTP methods. If we want 
49
+to create a new training then we call the first URL. If we want to read 
50
+training data, or update data, or delete a training then we use the second URL 
51
+(just replace ```:training``` with some integer). Actually, REST force you take 
52
+an advantage of 
53
+[CRUD](http://en.wikipedia.org/wiki/Create,_read,_update_and_delete). And 
54
+that's good. As you can see, to make operations with trainings we need just two 
55
+URLs (I call them *access points*).
56
+
57
+The philosophy of REST is to access *objects*. In the example ```training``` 
58
+was the object. The reason is simple -- we can make CRUD operations (read, 
59
+write, update, delete) only with objects.
60
+
61
+# Another example
62
+
63
+Well, you can ask: "What if I need to tell a trainee X wants to join training 
64
+Y?". I solved the problem by creating another access point:
65
+
66
+	http://api.example.com/training/:training/attendance/:trainee/
67
+
68
+Now we are working with ```attendance``` object. Allowed HTTP methods for this 
69
+access point are PUT and DELETE. 
70
+If a trainee with ID 541 wants to join training with ID 1050 we call 
71
+```http://api.example.com/training/1050/attendance/541/``` with ```PUT``` 
72
+method. Later the trainee changes his mind and wants to leave the training, so 
73
+we call the same URL with ```DELETE``` method.
74
+
75
+# How to send data to server with cURL
76
+
77
+I'll illustrate using REST API with curl utility.
78
+
79
+## POST method:
80
+ 
81
+Let's create a new training:
82
+
83
+{% codeblock lang:bash %}
84
+	curl -X POST \
85
+		--data-urlencode "starts_at=2013-12-12 12:00" \
86
+		--data-urlencode "ends_at=2013-12-12 13:00" \
87
+		--data-urlencode "name=New training" \
88
+		http://api.example.com/training/
89
+{% endcodeblock %}
90
+
91
+A simplified server response can look like this (in JSON):
92
+
93
+{% codeblock lang:json %}
94
+{
95
+	"id"             : 800,
96
+	"name"           : "New training",
97
+	"starts_at"      : "2013-12-12T12:00:00+0100",
98
+	"ends_at"        : "2013-12-12T13:00:00+0100",
99
+	"created_at"     : "2013-10-06T17:23:12+0200",
100
+	"updated_at"     : "2013-10-06T17:23:12+0200"
101
+}
102
+{% endcodeblock %}
103
+
104
+## GET method:
105
+ 
106
+Now we know training ID. Getting information about training:
107
+
108
+{% codeblock lang:bash %}
109
+	curl http://api.example.com/training/123/
110
+{% endcodeblock %}
111
+
112
+We haven't changed training data so a server response looks exactly like in 
113
+above example.
114
+
115
+## PUT method:
116
+ 
117
+I made a mistake! The training should ends at 13:30, let's change it:
118
+ 
119
+{% codeblock lang:bash %} 
120
+	curl -X PUT \
121
+		--data-urlencode "ends_at=2013-12-12 13:30" \
122
+		http://api.example.com/training/800/
123
+{% endcodeblock %}
124
+
125
+A simplified server response:
126
+
127
+{% codeblock lang:json %}
128
+{
129
+	"id"             : 800,
130
+	"name"           : "New training",
131
+	"starts_at"      : "2013-12-12T12:00:00+0100",
132
+	"ends_at"        : "2013-12-12T13:30:00+0100",
133
+	"created_at"     : "2013-10-06T17:23:12+0200",
134
+	"updated_at"     : "2013-10-06T17:32:11+0200"
135
+}
136
+{% endcodeblock %}
137
+
138
+## DELETE method:
139
+
140
+This deletes training:
141
+
142
+{% codeblock lang:bash %}
143
+	curl -X DELETE \
144
+		http://api.example.com/training/800/
145
+{% endcodeblock %}
146
+
147
+An obligatory server response:
148
+
149
+{% codeblock lang:json %}
150
+{
151
+	"success" : true
152
+}
153
+{% endcodeblock %}