A common point of focus between POST and PUT (which I find technically correct but unsatisfying) is that PUT is idempotent — repeating the PUT has the same effect every time (HTTP/1.1 §9.1.2).
The reason I find the answer unsatisfying is twofold. First, It’s a rare word even as jargon so it doesn’t facilitate communication. Second, it assumes a common knowledge of the design vision undergirding the web. In practical experience, I find a surprising number of professionals who have never given the subject much thought. This is not to denigrate anyone — as in most human affairs, practical daily tasks generally do not entail active consideration of relevant larger principles. We have work to do, after all.
While quotidian use of the web revolves around browsing web sites and watching funny cat videos, there is a design framework underneath. RFC 1630 reminds us that it’s not just web pages with content to be consumed — there are a multitude of Internet-accessible resources. Consider the RFC’s description of a URL not as a web page address but as “an address which maps onto an access algorithm using network protocols”.
In other words, a URL is an address to access an algorithm. HTTP is a protocol — a formal method for accessing an algorithm.
The RESTful paradigm leverages this concept of accessing algorithms so that data can be created, retrieved, updated, and removed (the so-called CRUD paradigm). Retrieval is performed using GET, and removal is performed using DELETE.
PUT vs. POST
There is some debate about PUT vs. POST for creation, but I think that the W3C is fairly clear.
When a client uses PUT, it is stating “please store the following data under this URL”. Accessing the same URL should return the data. (The W3C steers clear of how this might affect the state of the server or the data). Conceptually, GET and PUT are analogous to read and write.
Of course, we’re not always writing to a known location. Appending a log, posting a new article to a site, sending mail, and recording data to a database with an autoincrementing primary key are common examples of data being handed over to the server without the assumption or knowability of the final URL.
POST simply requests “that the origin server accept the entity enclosed in the request”. If the POST results in data that can be accessed by a new URL, the server should return 201 (Created) and indicate the new location using, for example, a Location header.
Which to Use?
In my judgement, if the client know exactly where to record the data, PUT is the appropriate semantic, otherwise use POST.
For the work I do, CRUD — the create, read, update, delete cycle — most appropriately maps to POST, GET, PUT and DELETE because the client app does not know the final URL of the data it’s providing. It expects the server to handle the details of logging and database identifiers.
All that being said, if you only use POST requests, or only use PUT requests, there is no technical error which will cause the world to catch fire. Development frameworks universally support POST, but PUT is not always well-supported, requiring coding glue to be written. In this case I find using POST in a PUT semantic is entirely reasonable.
In the end I would say to understand the intent of the standards, and document what you’re doing.