---
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 %}
*This article was also published on my school [blog](http://cinan.blog.matfyz.sk/p94260)*.