Should I use PUT method for update, if I also update a timestamp attribute - rest

According to REST style, it's generally assumed that HTTP POST, GET, PUT, and DELETE methods should be used for CREATE, READ, UPDATE and DELETE (CRUD) operations.
But if we stick to the HTTP method definitions, it might not be so clear.
In this article it's explained that:
In a nutshell: use PUT if and only if you know both the URL where the resource will live, and the entirety of the contents of the resource. Otherwise, use POST.
Mainly because
PUT is a much more restrictive verb. It takes a complete resource and stores it at the given URL. If there was a resource there previously, it is replaced; if not, a new one is created. These properties support idempotence, which a naive create or update operation might not. I suspect this may be why PUT is defined the way it is; it's an idempotent operation which allows the client to send information to the server.
In my case I usually issue updates passing all the resource data, so I could use PUT for updates, but every time I issue an update I save a LastUser and LastUpdate column, with the user id that made the modification and the time of the operation.
I'd like to know your opinion, because strictly speaking those two columns are not part of the resource, but they do prevent the operation from being idempotent.

Ignoring the comment about the REST style mapping CRUD to the HTTP methods, this is an excellent question.
The answer to your question is, yes you are free to use PUT in this scenario even though there are some elements of the resource that are updated by the server in a non-idempotent manner. Unfortunately, the reasoning behind the answer is quite vague. The important thing, is to understand what was the intent of the client request. The client intended to completely replace the contents of resource with the values passed. The client is not responsible for the server doing other operations and therefore the semantics of the HTTP method are not violated.
This is the reasoning that is used to allow a server to update a page counter when you do a GET operation. The client didn't ask for an update therefore the GET is safe even though the server chose to make an update.
The whole, complete resource versus partial resource debate has finally been spelled out in an update to the HTTP spec
An origin server SHOULD reject any PUT
request that contains a
Content-Range header field, since it
might be misinterpreted as partial
content (or might be partial content
that is being mistakenly PUT as a
full representation). Partial content
updates are possible by targeting a
separately identified resource with
state that overlaps a portion of
the larger resource, or by using a
different method that has been
specifically defined for partial
updates (for example, the PATCH
method defined in [RFC5789]).
So, what we are supposed to do is now clear. What is not so clear is why there exists this constraint on only being allowed to send full responses. That question has been asked and IMHO remains unanswered in this thread on rest-discuss.

As LastUser and LastUpdate are not modifiable by the client, I'd remove them from the representation of your resource altogether. Let me explain my reasoning with an example.
Let's say that our typical example API will return the following representation to the client when asked to provide a single resource:
GET /example/123
<?xml version="1.0" encoding="UTF-8" ?>
<example>
<id>123</id>
<lorem>ipsum</lorem>
<dolor>sit amet</dolor>
<lastUser uri="/user/321">321</lastUser>
<lastUpdate>2011-04-16 20:00:00 GMT</lastUpdate>
</example>
If a client wants to modify the resource, it would presumably take the whole representation and send it back to the API.
PUT /example/123
<?xml version="1.0" encoding="UTF-8" ?>
<example>
<id>123</id>
<lorem>foobar</lorem>
<dolor>foobaz</dolor>
<lastUser>322</lastUser>
<lastUpdate>2011-04-16 20:46:15 GMT+2</lastUpdate>
</example>
Since the API generates values for lastUser and lastUpdate automatically and cannot accept data provided by the client, the most appropriate response would be 400 Bad Request or 403 Forbidden (since the client cannot modify these values).
If we want to be compliant with REST and send a full representation of the resource when doing a PUT request, we need to remove lastUser and lastUpdate from the representation of the resource. This will allow clients to send the full entity via PUT:
PUT /example/123
<?xml version="1.0" encoding="UTF-8" ?>
<example>
<id>123</id>
<lorem>foobar</lorem>
<dolor>foobaz</dolor>
</example>
The server would accept a full representation now that it doesn't contain lastUpdate and lastUser.
The question that remains is how to provide clients with access to lastUpdate and lastUser. If they don't need it (and these fields are required just internally by the API), we are fine and our solution is perfectly RESTful. If however clients need access to this data, the cleanest approach would be to use HTTP headers:
GET /example/123
...
Last-Modified: Sat, 16 Apr 2011 18:46:15 GMT
X-Last-User: /user/322
...
<?xml version="1.0" encoding="UTF-8" ?>
<example>
<id>123</id>
<lorem>foobar</lorem>
<dolor>foobaz</dolor>
</example>
Using a custom HTTP header is not ideal because user agents need to be taught on how to read it. If we want to provide clients with access to the same data in a more easier way, the only thing that we can do is to put the data into the representation, and we are facing the same problem as in your original question. I would at least try to mitigate it somehow. If the content type used by the API is XML, we can put the data into node attributes instead of exposing them directly as node values, i.e.:
GET /example/123
...
Last-Modified: Sat, 16 Apr 2011 18:46:15 GMT
...
<?xml version="1.0" encoding="UTF-8" ?>
<example last-update="2011-04-16 18:46:15 GMT" last-user="/user/322">
<id>123</id>
<lorem>foobar</lorem>
<dolor>foobaz</dolor>
</example>
This way we'll at least avoid the problem where a client would attempt to submit all XML nodes in a follow-up PUT request. This won't work with JSON, and the solution is still a bit on the edge of idempotency (since the API would still have to ignore the XML attributes when processing the request).
Even better, as Jonah pointed out in the comments, if clients need access to lastUser and lastUpdate, these can be exposed as a new resource, linked from the original one e.g. as follows:
GET /example/123
<?xml version="1.0" encoding="UTF-8" ?>
<example>
<id>123</id>
<lorem>foobar</lorem>
<dolor>foobaz</dolor>
<lastUpdateUri>/example/123/last-update</lastUpdateUri>
</example>
... and then:
GET /example/123/last-update
<?xml version="1.0" encoding="UTF-8" ?>
<lastUpdate>
<resourceUri>/example/123</resourceUri>
<updatedBy uri="/user/321">321</updatedBy>
<updatedAt>2011-04-16 20:00:00 GMT</updatedAt>
</lastUpdate>
(The above can be also nicely expanded to provide a full audit log with individual changes, providing a resource changelog is available.)
Please note:
I agree with Darrel Miller's take on the question, but I wanted to provide a different approach on top of it. Note that this approach is not backed-up by any standards/RFCs/etc, it's just a different take on the problem.

The disadvantage of using PUT to create resources is that the client has to provide the unique ID that represents the object it is creating. While it usually possible for the client to generate this unique ID, most application designers prefer that their servers (usually through their databases) create this ID. In most cases we want our server to control the generation of resource IDs. So what do we do? We can switch to using POST instead of PUT.
So:
Put = UPDATE
Post = INSERT
Hopefully, this helps for your specific case.

The HTTP methods POST and PUT aren't the HTTP equivalent of the CRUD's create and update. They both serve a different purpose. It's quite possible, valid and even preferred in some occasions, to use PUT to create resources, or use POST to update resources.
Use PUT when you can update a resource completely through a specific resource. For instance, if you know that an article resides at http://example.org/article/1234, you can PUT a new resource representation of this article directly through a PUT on this URL.
If you do not know the actual resource location, for instance, when you add a new article, but do not have any idea where to store it, you can POST it to an URL, and let the server decide the actual URL.

Related

RESTful - How to update a subresource and what ETag/payload to return concerning optimistic locking?

As an example I have an order where the invoicing address can be modified. The change might trigger various additional actions (i.e. create a cancellation invoice and a new invoice with the updated address).
As recommended by various sources (see below) I don't want to have a PATCH on the order resource, because it has many other properties, but want to expose a dedicated endpoint, also called "intent" resource or subresource according to the web links below:
/orders/{orderId}/invoicing-address
Should I use a POST or a PATCH against this subresource?
The invoicing address itself has no ID. In the domain layer it is represented as a value object that is part of the order entity.
What ETag should be used for the subresource?
The address is part of the order and together with the items they form an aggregate in the domain layer. When the aggregate is updated it gets a new version number in the database. That version number is used as an ETag for optimistic locking.
Should a GET on invoicing-address respond with the order aggregate version number or a hash value of the address DTO in the ETag header?
What payload should be returned after updating the address?
Since the resource is the invoicing address it seems natural to return the updated address object (maybe with server side added fields). Should the body also include the ID/URI and the ETag of the order resource?
None of the examples I found with subresources showed any server responses or considered optimistic locking.
https://rclayton.silvrback.com/case-against-generic-use-of-patch-and-put
https://www.thoughtworks.com/insights/blog/rest-api-design-resource-modeling
https://softwareengineering.stackexchange.com/questions/371273/design-update-properties-on-an-entity-in-a-restful-resource-based-api (see provided answer)
https://www.youtube.com/watch?v=aQVSzMV8DWc&t=188s (Jim Webber at about about 31 mins)
As far as REST is concerned, "subresources" aren't a thing. /orders/12345/invoicing-address identifies a resource. The fact that this resource has a relationship with another resource identified by /orders/12345 is irrelevant.
Thus, the invoicing-address resource should understand HTTP methods exactly the same way as every other resource on the web.
Should I use a POST or a PATCH against this subresource?
Use PUT/PATCH if you are proposing a direct change to the representation of the resource. For example, these are the HTTP methods we would use if we were trying to fix a spelling error in an HTML document (PUT if we were sending a complete copy of the HTML document; PATCH if we were sending a diff).
PUT /orders/12345/invoicing-address
Content-Type: text/plain
1060 W Addison St.
Chicago, IL
60613
On the other hand, if you are proposing an indirect change to the representation of the resource (the request shows some information to the server, and the server is expected to compute a new representation itself)... well, we don't have a standardized method that means exactly that; therefore, we use POST
POST serves many useful purposes in HTTP, including the general purpose of “this action isn’t worth standardizing.” -- Fielding, 2009
What ETag should be used for the subresource?
You should first give some thought to whether you want to use a strong-validator or a weak validator
A strong validator is representation metadata that changes value whenever a change occurs to the representation data that would be observable in the content of a 200 (OK) response to GET.
...
In contrast, a weak validator is representation metadata that might
not change for every change to the representation data.
...
a weak entity-tag ought to change whenever the origin server wants caches to invalidate old responses.
I might use a weak validator if the representation included volatile but insignificant information; I don't need clients to refresh their copy of a document because it doesn't have the latest timestamp metadata. But I probably wouldn't use an "aggregate version number" if I expected the aggregate to be changing more frequently than the invoicing-address itself changes.
What payload should be returned after updating the address?
See 200 OK.
In the case of a POST request, sending the current representation of the resource (after changes have been made to it) is nice because the response is cacheable (assuming you include the appropriate metadata signals in the response headers).
Responses to PATCH have similar rules to POST (see RFC 5789).
PUT is the odd man out, here
Responses to the PUT method are not cacheable.
Should the body also include the ID/URI and the ETag of the order resource?
Entirely up to you - HTTP components aren't going to be paying attention to the representation, so you can design that representation as makes sense to you. On the web, it's perfectly normal to return HTML documents with links to other HTML documents.

RSA Archer API Resource and Content Clarification

I can access both the RSA REST and WSDL based APIs. Their documents refer to content and resourses. However, when logging into the actual tool I can access things like incident ticket and the like.
Incidents tickets will have INC-1234 which would be a string. But the API takes integer values for either content or resource when searching by ID.
self.wsdl['search'].service.SearchRecordsByReport(
sessionToken=self.token,
reportIdOrGuid=14,
pageNumber=1
)
If I don't provide an integer i get a 404 with a simple
"Message": "The request is invalid." in the REST
and something a little more complex if i pass a value like that in SOAP
So, Question 1. is there an RSA resource that correlates/demystifies the relationships of calls in the API with the actual names of things I'm dealing with the in the UI.
Question 2. Is there a code library were someone has created/modified rsa incident tickets before out there?
If you're talking about getting the record contentID you can get it two ways, in the GUI hover over your key field (the clickable link) and in the bottom left corner of archer it'll show something similar to "123456|100|17" where the first set is the contentID of that record.
If you're talking about getting a reportID (14 like you've shown above) you can do the same thing when you go to the master reports list, and it'll show in the bottom right corner of your browser.
If you want to do it all from code I usually piece it together like this:
Execute a search of a report; Get the field IDs from the report <FieldDefinition> (it's probably important to make sure your keyfield is included on the report GUI so you'll be able to identify which record you're dealing with); make another API call (probably REST since it really handles the metadata) to get the field name etc. (or you could make it all static and just hard-code the field names with the corresponding GUIDS)
Within the <Record> tag, you can snag the contentID attribute. Then take a step down and compare the field tag that matches your keyfield and you'll have the contentID of that record.
Make record updates, deletes, etc whatever you need to do.
If you're looking for a specific report ID, make a REST call to get all reports, and it'll return report names and IDs, and then go about your business making your other calls.
I've recently came across similar situation where I have to search for a field value (e.g. "INC-1234") using Archer's API.
So, for your Question 1:
The method that I found convenient to my requirements is "ExecuteQuickSearchWithModuleIds" which can search for a value and provides all ContentIDs that have those values (given the ModuleId).
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<ExecuteQuickSearchWithModuleIds xmlns="http://archer-tech.com/webservices/">
<sessionToken>ABC123ABC123ABC123ABC123ABC1</sessionToken>
<moduleIds>123</moduleIds>
<keywords>INC-1234</keywords>
<pageNumber>9999999</pageNumber>
<pageSize>9999999</pageSize>
</ExecuteQuickSearchWithModuleIds>
</soap:Body>
</soap:Envelope>
And for your Question 2, I found a rich library for Python3 Archer RSA.
Hope this helps someone who lands on this question.

Restrict updates to specific fields in RESTful API

Let's say I have an object, Widget, comprised of an Id and a Name. Let's say I expose an endpoint, /widget, where clients can POST new Widget objects. If I want the Id field to always be set by the server, not modifiable by the client, but still visible to clients, how can I declare that the Id field is not modifiable? I'm using RESTeasy if that makes any difference.
I can think of a few options.
First, are you sure you need to expose the ID as part of the representation? Or is it enough to respond with the location of the new posted resource?
Your client posts:
<Resource><Name>New Resource</Name></Resource>
And you respond:
HTTP/1.1 201 Created
...
Location: /resources/{new_resource_id}
Beyond that, I think it's OK to have some simple, well-understood conventions with your clients. I think most developers understand that an ID is likely to be system-generated (especially, since you're doing a POST and not a PUT). For less obvious cases, where you have arbitrary read-only fields (or other validation or display information), I think it may make sense to provide a link to metadata:
<NewPersonForm>
<atom:link href="/people/new/metadata" rel="/rels/metadata" />
<Name />
<Department>HR</Department>
</NewPersonForm>
What the metadata looks like is up to you, but something along these lines might work for you:
<Metadata>
<Element>
<Name>Department</Name>
<IsReadOnly>True</IsReadOnly>
</Element>
</Metadata>
That's a nice, format-neutral (it works well for both XML and JSON) way to provide information to the client, and if they really want to, they can program against it to build forms on the fly (I use it to provide validation information, language-specific labels, and data type information).
I hope this helps.
John
You write the code on the server that free to do whatever it wants. And that includes adding or changing data as needed. Check the AtomPub protocol section 9.2 that explicitly states:
Since the server is free to alter the
POSTed Entry, for example, by changing
the content of the atom:id element,
returning the Entry can be useful to
the client, enabling it to correlate
the client and server views of the new
Entry.

REST - GET returns different result than POST/PUT

In our project, a book can be added by sending the book structure (in XML, JSON, ..) via a POST or PUT request. For example, in XML, the book structure looks like this (simplified):
<book>
<title>My Book</title>
<author>John Q.</author>
</book>
When this book is inserted in our backend database, some auto-generated properties are automatically added, such as the creation date, the user id who submitted the book, an identifier, ...
When the book is retrieved through a GET, these additional properties are included in the book definition:
<book>
<title>My Book</title>
<author>John Q.</author>
<info>
<creation_date>2011...</creation_data>
<user_id>48</user_id>
<identifier>my_book_john_q</identifier>
</info>
</book>
This basically means that the XML scheme of a new/edited book (= from client to server) is different than a retrieved book (= from server to client). This makes things confusing.
A possiblity is to make these additional properties available in a different URI, for example:
http://server/books/:id/ -> returns the short version
http://server/books/:id/information/ -> returns the generated properties
A downside of this approach is that two separate requests are needed to have all data.
How would you solve this inconsistency?
This is perfectly normal. There is no problem having the server augment the representation with some additional information. A good example of this is when the server adds links to the representation. There is no requirement for the client to send "copies" of those links to the server when doing a PUT. The resource representations that you GET and PUT should be conceptually the same, not necessarily byte for byte identical.
You're not using mimetypes correctly. I bet you're using an application/xml generic mimetype and your clients know what to expect based on the endpoint, right?
The proper way to deal with your problem would be having different representations for the same resource, with different mimetypes. For instance, you can have a application/vnd.yourcompany.book.short+xml for the short representation, and application/vnd.yourcompany.book+xml for the complete representation. Clients can use the Content-Type header to say which one they are sending, and the Accept header to say which one they want.
This doesn't mean the clients must send the short representation in the POST or PUT. You can document some fields as optional and it's perfectly fine for the clients to omit them.

Why do we need anything more than HTTP GET, PUT, POST?

What is the practical benefit of using HTTP GET, PUT, DELETE, POST, HEAD? Why not focus on their behavioral benefits (safety and idempotency), forgetting their names, and use GET, PUT or POST depending on which behavior we want?
Why shouldn't we only use GET, PUT and POST (and drop HEAD, DELETE)?
The [REST][1] approach uses POST, GET, PUT and DELETE to implement the CRUD rules for a web resource. It's a simple and tidy way to expose objects to requests on the web. It's web services without the overheads.
Just to clarify the semantic differences. Each operation is rather different. The point is to have nice HTTP methods that have clear, distinct meanings.
POST creates new objects. The URI has no key; it accepts a message body that defines the object. SQL Insert. [Edit While there's no technical reason for POST to have no key, the REST folks suggest strongly that for POST to have distinct meaning as CREATE, it should not have a key.]
GET retrieves existing objects. The URI may have a key, depends on whether you are doing singleton GET or list GET. SQL Select
PUT updates an existing object. The URI has a key; It accepts a message body that updates an object. SQL Update.
DELETE deletes an existing object. The URI has a key. SQL Delete.
Can you update a record with POST instead of PUT? Not without introducing some ambiguity. Verbs should have unambiguous effects. Further, POST URI's have no key, where PUT must have a key.
When I POST, I expect a 201 CREATED. If I don't get that, something's wrong. Similarly, when I PUT, I expect a 200 OK. If I don't get that, something's wrong.
I suppose you could insist on some ambiguity where POST does either POST or PUT. The URI has to be different; also the associated message could be different. Generally, the REST folks take their cue from SQL where INSERT and UPDATE are different verbs.
You could make the case that UPDATE should insert if the record doesn't exist or update if the record does exist. However, it's simpler if UPDATE means UPDATE and failure to update means something's wrong. A secret fall-back to INSERT makes the operation ambiguous.
If you're not building a RESTful interface, then it's typical to only use GET and POST for retrieve and create/update. It's common to have URI differences or message content differences to distinguish between POST and PUT when a person is clicking submit on a form. It, however, isn't very clean because your code has to determine if you're in the POST=create case or POST=update case.
POST has no guarantees of safety or idempotency. That's one reason for PUT and DELETE—both PUT and DELETE are idempotent (i.e., 1+N identical requests have the same end result as just 1 request).
PUT is used for setting the state of a resource at a given URI. When you send a POST request to a resource at a particular URI, that resource should not be replaced by the content. At most, it should be appended to. This is why POST isn't idempotent—in the case of appending POSTS, every request will add to the resource (e.g., post a new message to a discussion forum each time).
DELETE is used for making sure that a resource at a given URI is removed from the server. POST shouldn't normally be used for deleting except for the case of submitting a request to delete. Again, the URI of the resource you would POST to in that case shouldn't be the URI for the resource you want to delete. Any resource for which you POST to is a resource that accepts the POSTed data to append to itself, add to a collection, or to process in some other way.
HEAD is used if all you care about is the headers of a GET request and you don't want to waste bandwidth on the actual content. This is nice to have.
Why do we need more than POST? It allows data to flow both ways, so why would GET be needed? The answer is basically the same as for your question. By standardizing the basic expectations of the various methods other processes can better know what to do.
For example, intervening caching proxies can have a better chance of doing the correct thing.
Think about HEAD for instance. If the proxy server knows what HEAD means then it can process the result from a previous GET request to provide the proper answer to a HEAD request. And it can know that POST, PUT and DELETE should not be cached.
No one posted the kind of answer I was looking for so I will try to summarize the points myself.
"RESTful Web Services" chapter 8 section "Overloading POST" reads: "If you want to do without PUT and DELETE altogether, it’s entirely RESTful to expose safe operations on resources through GET, and all other operations through overloaded POST. Doing this violates my Resource-Oriented Architecture, but it conforms to the less restrictive rules of REST."
In short, replacing PUT/DELETE in favor of POST makes the API harder to read and PUT/DELETE calls are no longer idempotent.
In a word:
idempotency
In a few more words:
GET = safe + idempotent
PUT = idempotent
DELETE = idempotent
POST = neither safe or idempotent
'Idempotent' just means you can do it over and over again and it will always do exactly the same thing.
You can reissue a PUT (update) or DELETE request as many times as you want and it will have the same effect every time, however the desired effect will modify a resource so it is not considered 'safe'.
A POST request should create a new resource with every request, meaning the effect will be different every time. Therefore POST is not considered safe or idempotent.
Methods like GET and HEAD are just read operations and are therefore considered 'safe' aswell as idempotent.
This is actually a pretty important concept because it provides a standard/consistent way to interpret HTTP transactions; this is particularly useful in a security context.
Not all hosters don't support PUT, DELETE.
I asked this question, in an ideal world we'd have all the verbs but....:
RESTful web services and HTTP verbs
HEAD is really useful for determining what a given server's clock is set to (accurate to within the 1 second or the network round-trip time, whichever is greater). It's also great for getting Futurama quotes from Slashdot:
~$ curl -I slashdot.org
HTTP/1.1 200 OK
Date: Wed, 29 Oct 2008 05:35:13 GMT
Server: Apache/1.3.41 (Unix) mod_perl/1.31-rc4
SLASH_LOG_DATA: shtml
X-Powered-By: Slash 2.005001227
X-Fry: That's a chick show. I prefer programs of the genre: World's Blankiest Blank.
Cache-Control: private
Pragma: private
Connection: close
Content-Type: text/html; charset=iso-8859-1
For cURL, -I is the option for performing a HEAD request. To get the current date and time of a given server, just do
curl -I $server | grep ^Date
To limit ambiguity which will allow for better/easier reuse of our simple REST apis.
You could use only GET and POST but then you are losing out on some of the precision and clarity that PUT and DELETE bring. POST is a wildcard operation that could mean anything.
PUT and DELETE's behaviour is very well defined.
If you think of a resource management API then GET, PUT and DELETE probably cover 80%-90% of the required functionality. If you limit yourself to GET and POST then 40%-60% of your api is accessed using the poorly specified POST.
Web applications using GET and POST allow users to create, view, modify and delete their data, but do so at a layer above the HTTP commands originally created for these purposes. One of the ideas behind REST is a return to the original intent of the design of the Web, whereby there are specific HTTP operations for each CRUD verb.
Also, the HEAD command can be used to improve the user experience for (potentially large) file downloads. You call HEAD to find out how large the response is going to be and then call GET to actually retrieve the content.
See the following link for an illustrative example. It also suggests one way to use the OPTIONS http method, which hasn't yet been discussed here.
There are http extensions like WebDAV that require additional functionally.
http://en.wikipedia.org/wiki/WebDAV
The web server war from the earlier days probably caused it.
In HTTP 1.0 written in 1996, there were only GET, HEAD, and POST. But as you can see in Appendix D, vendors started to add their own things. So, to keep HTTP compatible, they were forced to make HTTP 1.1 in 1999.
However, HTTP/1.0 does not sufficiently take into consideration
the effects of hierarchical proxies, caching, the need for
persistent connections, or virtual hosts. In addition, the proliferation
of incompletely-implemented applications calling themselves
"HTTP/1.0" has necessitated a protocol version change in order for
two communicating applications to determine each other's true capabilities.
This specification defines the protocol referred to as "HTTP/1.1". This protocol includes more stringent requirements than HTTP/1.0 in order
to ensure reliable implementation of its features.
GET, PUT, DELETE and POST are holdovers from an era when sophomores thought that a web page could be reduced to a few hoighty-toity principles.
Nowadays, most web pages are composite entities, which contain some or all of these primitive operations. For instance, a page could have forms for viewing or updating customer information, which perhaps spans a number of tables.
I usually use $_REQUEST[] in php, not really caring how the information arrived. I would choose to use GET or PUT methods based on efficiency, not the underlying (multiple) paradigms.