If you mix everything, you're probably not doing REST. From RESTful Web services: The basicsPOST and PUT have distinct usage scenario:
To create a resource on the server, use POST.
To retrieve a resource, use GET.
To change the state of a resource or to update it, use PUT.
To remove or delete a resource, use DELETE.
So consider POST as posting a new ticket to a blog and PUT to change an existing value.
Removing should be done as a distinctive operation with the DELETE verb. As "remove all" before update doesn't sound like a good idea.
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.
I therefore think that the use of PUT for an insert or update is perfectly legitimate, provided that in both cases the URI is known in advance. If you're using the key as part of the URI (as k1 in http://www.somewhere.com/resources/k1) this should be the case. To be ideally RESTful, however, a GET to the same URL should also allow you to download the resource.
Also I have another operation which remove all existing keys and add the new key, is this POST or PUT because it clear records and add new one.
I don't think this operation could be considered RESTful because it does two things. It seems to be providing a macro to satisfy the needs of a particular client, rather than simple access to data. A standard RESTful design would be
It's less clear cut, but I think it would also be legitimate to delete all resources by sending a single DELETE request to http://www.somewhere.com/resources.
The idea behind upsert operation is that clients have information about/decide on data structure and sending data with key value. So request model for upsert operation is very similar to update operation with key included as the example below:
/customers/jimmy
The expected method for updating an existing record is PUT. So your choice should be PUT.
POST is generally used for inserting a new record with a brand new content like in the example below:
POST /customers HTTP/1.1
Content-Type: ...
Content-Length: ...
Host: server.yourdomain.com
Accept: ...
User-Agent: ...
id jimmy
name jimmy
Occupation Stackoverflower
So in your case you do not need any POST operation because PUT for upsert operation also covers that.
Here the critical question about upsert is how likely you trust your client about upsert operation. If a client desires to insert a new record with an existing key what happens? In your case you should handle this request as an update because both insert and update requests come to the same api and you have an existing record. This is the question to be answered on your side about design.
Polly Shaw's answer is correct, but I would like to mention that given that the message might very likely be incomplete (missing the ID when the resource is not yet created), a PATCH verb would be slightly more correct.
PUT needs to be idempotent. This means if you PUT the same payload a second time the system state should not be changed.
If the intended payload is a mix of new and existing and the expected behavior would be to create more new records the second time around then it would seem 'upsert' would line up more closely with POST.
We strive to create mistake tolerant APIs. If you cannot make the PUT idempotent and they must use it they could corrupt the system. On the other hand POST is not expected to be idempotent, so if you sent update-only data (over and over) in the payload (even though this technically violates the idempotency rule for POST because it did not change the state of the system by adding records on subsequent calls) the system would (probably) not be corrupted.
The spec says PUT "can" add new items and "must" be idempotent
It says POST "must" add new items and is not idempotent
If you really want to implement an upsert neither is perfect, but if mistakes cause corruption on PUT the API is to blame (its supposed to be idempotent) whereas corruption on POST is "I told you so".
I also like to think about what the API consumer will be looking for. Commonly a UI dev working on a new screen will be looking to add the records the user has added in the UI. He'll be looking for a POST first, then discover that it also handles the PUT side of the equation.
So, neither, but if you have to choose, choose POST.
The HTTP PUT request method creates a new resource or replaces a representation of the target resource with the request payload.
The difference between PUT and POST is that PUT is idempotent: calling
it once or several times successively has the same effect (that is no
side effect), whereas successive identical POST requests may have
additional effects, akin to placing an order several times.
If the target resource does not have a current representation and the
PUT request successfully creates one, then the origin server must
inform the user agent by sending a 201 (Created) response.
HTTP/1.1 201 Created
Content-Location: /new.html
If the target resource does have a current representation and that
representation is successfully modified in accordance with the state
of the enclosed representation, then the origin server must send
either a 200 (OK) or a 204 (No Content) response to
indicate successful completion of the request.
HTTP/1.1 204 No Content
Content-Location: /existing.html