Tuesday, November 13, 2012

RESTful API memo: PUT and POST differences

Before start designing a RESTful API, have a look at Hypertext Transfer Protocol -- HTTP/1.1, section 9

"The POST method is used to request that the origin server accept the entity enclosed in the request as a new subordinate of the resource identified by the Request-URI in the Request-Line.".

In other terms, POST is meant to handle appends to existing resources or incremental creations of subordinate resources:

"The actual function performed by the POST method is determined by the server and is usually dependent on the Request-URI. The posted entity is subordinate to that URI in the same way that a file is subordinate to a directory containing it, a news article is subordinate to a newsgroup to which it is posted, or a record is subordinate to a database."

PUT instead seems is more appropriate to handle one-shot creations, creating or replacing an entire resource in one single transaction:

"The PUT method requests that the enclosed entity be stored under the supplied Request-URI. If the Request-URI refers to an already existing resource, the enclosed entity SHOULD be considered as a modified version of the one residing on the origin server. If the Request-URI does not point to an existing resource, and that URI is capable of being defined as a new resource by the requesting user agent, the origin server can create the resource with that URI."

Differences between PUT and POST:

"The fundamental difference between the POST and PUT requests is reflected in the different meaning of the Request-URI. The URI in a POST request identifies the resource that will handle the enclosed entity. That resource might be a data-accepting process, a gateway to some other protocol, or a separate entity that accepts annotations. In contrast, the URI in a PUT request identifies the entity enclosed with the request -- the user agent knows what URI is intended and the server MUST NOT attempt to apply the request to some other resource."

Another remarkable difference is that PUT requests are required to be idempotent, while POST are not:

"Methods can also have the property of 'idempotence' in that (aside from error or expiration issues) the side-effects of N > 0 identical requests is the same as for a single request. The methods GET, HEAD, PUT and DELETE share this property. Also, the methods OPTIONS and TRACE SHOULD NOT have side effects, and so are inherently idempotent."

Saturday, November 10, 2012

Creating your private Git repository on Dropbox in less than 5 minutes

Github is the tool I use daily to manage my public software projects, I love it. But sometimes I have to quickly and temporarily share private projects with colleagues or maybe even in a mixed environment, with customers and consultants from other companies. When there is no time / money to buy private remote repos from Github or even install a local Git repo on some server,  and for privacy constraints it is not possibile to publish the code on a public Github repo, then Dropbox comes to the rescue.

In this example I'm working on a simple Web application in Flask, which is a cool Python micro-framework. I created a "flask_sample" folder which contains the code I want to version with Git and share with other colleagues.

I promised it will take less than 5 minutes, so let's start.

Move to your Dropbox folder (in my case it's in /Users/mturatti/Dropbox/) and create a folder to host all your remote git repositories:

$ cd /Users/mturatti/Dropbox/
$ mkdir git

Then create here the folder to host this remote repository:

$ cd git
$ mkdir flask_sample.git
$ cd flask_sample.git

It's time to create a bare Git repository:

$ git init --bare

You'll see it creates a structure similar to the following:

mturatti:~/Dropbox/git/flask_sample.git$ ls -l
total 24
-rw-r--r--   1 mturatti  staff   23  9 Nov 18:38 HEAD
-rw-r--r--   1 mturatti  staff  112  9 Nov 18:38 config
-rw-r--r--   1 mturatti  staff   73  9 Nov 18:38 description
drwxr-xr-x  10 mturatti  staff  340  9 Nov 18:38 hooks
drwxr-xr-x   3 mturatti  staff  102  9 Nov 18:38 info
drwxr-xr-x  11 mturatti  staff  374  9 Nov 19:09 objects
drwxr-xr-x   4 mturatti  staff  136  9 Nov 18:38 refs

Now you have in place a git structure which can act as a shareable remote repository, even if in practice it's local to your hard disk. Being a Dropbox folder will do the magic in terms of backups, sharing and synchronization.

Initialize Git in your software project as usual (in my case the local project stays in /Users/mturatti/src/flask_sample)

$ git init

This creates the usual hidden .git folder.
The last configuration step is to add locally the previously created remote Git repository:

$ git remote add origin file:///Users/mturatti/Dropbox/git/flask_sample.git

Note we are using the file:// protocol for the remote Git repository here.
If you check the content of .git/config file you'll see the new origin (in bold below):

mturatti:~/src/flask_sample$ cat .git/config 

[core]
repositoryformatversion = 0
filemode = true
bare = false
logallrefupdates = true
ignorecase = true
precomposeunicode = false
[remote "origin"]
url = file:///Users/mturatti/Dropbox/git/flask_sample.git
fetch = +refs/heads/*:refs/remotes/origin/*

At this point you can start the usual Git lifecycle. For example, after you have added and committed all your files locally, you can "push to origin", which will push your code to your remote Git repository saved on Dropbox:

$ git push origin master

The last step will be to share the Dropbox folder with your colleagues, so that they can also add this as a remote repository and start cloning / pulling / pushing from this origin.