Choosing between safe and unsafe HTTP Method when creating MVC action - asp.net

I'm generally following the recommendations when it comes to choosing between HTTP GET and HTTP POST as allowed method for action on controller in ASP.NET MVC.
When there is no change on server side, aka I want to retrieve a resource, HTTP GET is allowed.
When user is about to submit some data that will be persisted, HTTP POST is required.
Now here comes the issue with the gray zone:
What if user wants to download a file?
Usually I would set this as HTTP GET (file is stored in database due to security reasons) as there is no change done on the server.
What if I want to log that file X was downloaded by user Y?
There is now server-side change as new log is created. Is that a good enough reason to change HTTP method from GET to POST?

I've found exact explanation on how to deal with this:
http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html
Definition of safe methods:
9.1.1 Safe Methods
Implementors should be aware that the software represents the user in
their interactions over the Internet, and should be careful to allow
the user to be aware of any actions they might take which may have an
unexpected significance to themselves or others.
In particular, the convention has been established that the GET and
HEAD methods SHOULD NOT have the significance of taking an action
other than retrieval. These methods ought to be considered "safe".
This allows user agents to represent other methods, such as POST, PUT
and DELETE, in a special way, so that the user is made aware of the
fact that a possibly unsafe action is being requested.
Naturally, it is not possible to ensure that the server does not
generate side-effects as a result of performing a GET request; in
fact, some dynamic resources consider that a feature. The important
distinction here is that the user did not request the side-effects, so
therefore cannot be held accountable for them.
Important part is emphasized below, which gives resolution to my problem:
Naturally, it is not possible to ensure that the server does not
generate side-effects as a result of performing a GET request; in
fact, some dynamic resources consider that a feature. The important
distinction here is that the user did not request the side-effects, so
therefore cannot be held accountable for them.
So since user did not request the logging to be performed, it is considered to be side-effect and therefore I can continue setting GET as HTTP method for file download.

Related

HTTP verb GET or PATCH or POST or PUT when call increments views

I have an end point like this
/profiles/1
I want to get the profile whose id is 1 but at the same time increment the visited property by 1. The property comes as part of the object. Which HTTP verb I should be using to fetch the profile object with visited property incremented by 1.
Everytime a profile with id: 1 is fetched, the visited property will be incremented by 1.
Which HTTP verb I should be using to fetch the profile object with visited property incremented by 1?
The GET method is meant to be used for data retrieval, so it's a candidate. Quoting the RFC 7231, the document that currently defines the semantics and contents of the HTTP/1.1 protocol:
4.3.1. GET
The GET method requests transfer of a current selected representation for the target resource. GET is the primary mechanism of information retrieval and the focus of almost all performance optimizations. [...]
The GET method is also defined as both safe (read-only) and idempotent (multiple identical requests with that method is the same as the effect for a single such request).
But it's still on the table. Again, quoting the RFC 7231 (highlights are mine):
4.2.1. Safe Methods
Request methods are considered "safe" if their defined semantics are essentially read-only; i.e., the client does not request, and does not expect, any state change on the origin server as a result of applying a safe method to a target resource. [...]
This definition of safe methods does not prevent an implementation from including behavior that is potentially harmful, that is not entirely read-only, or that causes side effects while invoking a safe method. What is important, however, is that the client did not request that additional behavior and cannot be held accountable for it. For example, most servers append request information to access log files at the completion of every response, regardless of the method, and that is considered safe even though the log storage might become full and crash the server. [...]
4.2.2. Idempotent Methods
A request method is considered "idempotent" if the intended effect on the server of multiple identical requests with that method is the same as the effect for a single such request. [...]
Like the definition of safe, the idempotent property only applies to what has been requested by the user; a server is free to log each request separately, retain a revision control history, or implement other non-idempotent side effects for each idempotent request.
Assuming you want to count the number of the times a profile is retrieved, then it makes sense to attach it to the GET operation. You may want, however, to avoid incrementing the counter when the endpoint is hit by a bot, for example.
So under certain conditions, GET requests are allowed to have side effects. What is important, however, is that the client did not request that additional behavior and cannot be held accountable for it: what a server does is the server's responsibility.
Ultimately, it's also important to say that HTTP doesn't care about the storage underneath, so you could either store the view count in the same table as the profile data or a different table or a completely different database. And then retrieve all together or use different endpoints for the view count.

What is the usefulness of PUT and DELETE HTTP request methods?

I've never used PUT or DELETE HTTP Request methods. My tendency is to use GET when the state of the system (my application or website) may not be affected (like a product listing) and to use POST when it is affected (like placing an order). Aren't those two always sufficient, or am I missing something?
DELETE is for deleting the request resource:
The DELETE method requests that the origin server delete the resource identified by the Request-URI. This method MAY be overridden by human intervention (or other means) on the origin server. The client cannot be guaranteed that the operation has been carried out, even if the status code returned from the origin server indicates that the action has been completed successfully …
PUT is for putting or updating a resource on the server:
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 …
For the full specification visit:
http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html
Since current browsers unfortunately do not support any other verbs than POST and GET in HTML forms, you usually cannot utilize HTTP to it's full extent with them (you can still hijack their submission via JavaScript though). The absence of support for these methods in HTML forms led to URIs containing verbs, like for instance
POST http://example.com/order/1/delete
or even worse
POST http://example.com/deleteOrder/id/1
effectively tunneling CRUD semantics over HTTP. But verbs were never meant to be part of the URI. Instead HTTP already provides the mechanism and semantics to CRUD a Resource (e.g. an order) through the HTTP methods. HTTP is a protocol and not just some data tunneling service.
So to delete a Resource on the webserver, you'd call
DELETE http://example.com/order/1
and to update it you'd call
PUT http://example.com/order/1
and provide the updated Resource Representation in the PUT body for the webserver to apply then.
So, if you are building some sort of client for a REST API, you will likely make it send PUT and DELETE requests. This could be a client built inside a browser, e.g. sending requests via JavaScript or it could be some tool running on a server, etc.
For some more details visit:
http://martinfowler.com/articles/richardsonMaturityModel.html
Are the PUT, DELETE, HEAD, etc methods available in most web browsers?
Why are there no PUT and DELETE methods in HTML forms
Should PUT and DELETE be used in forms?
http://amundsen.com/examples/put-delete-forms/
http://www.quora.com/HTTP/Why-are-PUT-and-DELETE-no-longer-supported-in-HTML5-forms
Using HTTP Request verb such as GET, POST, DELETE, PUT etc... enables you to build RESTful web applications. Read about it here: http://en.wikipedia.org/wiki/Representational_state_transfer
The easiest way to see benefits from this is to look at this example.
Every MVC framework has a Router/Dispatcher that maps URL-s to actionControllers.
So URL like this: /blog/article/1 would invoke blogController::articleAction($id);
Now this Router is only aware of the URL or /blog/article/1/
But if that Router would be aware of whole HTTP Request object instead of just URL, he could have access HTTP Request verb (GET, POST, PUT, DELETE...), and many other useful stuff about current HTTP Request.
That would enable you to configure application so it can accept the same URL and map it to different actionControllers depending on the HTTP Request verb.
For example:
if you want to retrive article 1 you can do this:
GET /blog/article/1 HTTP/1.1
but if you want to delete article 1 you will do this:
DELETE /blog/article/1 HTTP/1.1
Notice that both HTTP Requests have the same URI, /blog/article/1, the only difference is the HTTP Request verb. And based on that verb your router can call different actionController. This enables you to build neat URL-s.
Read this two articles, they might help you:
Symfony 2 - HTTP Fundamentals
Symfony 2 - Routing
These articles are about Symfony 2 framework, but they can help you to figure out how does HTTP Requests and Responses work.
Hope this helps!
Although I take the risk of not being popular I say they are not useful nowadays.
I think they were well intended and useful in the past when for example DELETE told the server to delete the resource found at supplied URL and PUT (with its sibling PATCH) told the server to do update in an idempotent manner.
Things evolved and URLs became virtual (see url rewriting for example) making resources lose their initial meaning of real folder/subforder/file and so, CRUD action verbs covered by HTTP protocol methods (GET, POST, PUT/PATCH, DELETE) lost track.
Let's take an example:
/api/entity/list/{id} vs GET /api/entity/{id}
/api/entity/add/{id} vs POST /api/entity
/api/entity/edit/{id} vs PUT /api/entity/{id}
/api/entity/delete/{id} vs DELETE /api/entity/{id}
On the left side is not written the HTTP method, essentially it doesn't matter (POST and GET are enough) and on the right side appropriate HTTP methods are used.
Right side looks elegant, clean and professional. Imagine now you have to maintain a code that's been using the elegant API and you have to search where deletion call is done. You'll search for "api/entity" and among results you'll have to see which one is doing DELETE. Or even worse, you have a junior programmer which by mistake switched PUT with DELETE and as URL is the same shit happened.
In my opinion putting the action verb in the URL has advantages over using the appropriate HTTP method for that action even if it's not so elegant. If you want to see where delete call is made you just have to search for "api/entity/delete" and you'll find it straight away.
Building an API without the whole HTTP array of methods makes it easier to be consumed and maintained afterwards
Safe Methods : Get Resource/No modification in resource
Idempotent : No change in resource status if requested many times
Unsafe Methods : Create or Update Resource/Modification in resource
Non-Idempotent : Change in resource status if requested many times
According to your requirement :
1) For safe and idempotent operation (Fetch Resource) use --------- GET METHOD
2) For unsafe and non-idempotent operation (Insert Resource) use--------- POST METHOD
3) For unsafe and idempotent operation (Update Resource) use--------- PUT METHOD
3) For unsafe and idempotent operation (Delete Resource) use--------- DELETE METHOD
See the accepted answer from #Gordon, the key point being simply this:
PUT and DELETE are specific verbs with a meaning, that instruct the server to do something specific and how the instruction should be handled.
OK standards and semantics are great but what real use is DELETE to me if all I want to do is somehow run code to delete something from a database?
So what if we say, "OK but it's easier for me to just do a delete by issuing a GET to my URI that has a path /api/entity/delete/{id} (as suggested in the answer by #Bogdan). OK so let's look at the definition of GET:
The GET method means retrieve whatever information (in the form of an
entity) is identified by the Request-URI
Source - W3C standards - https://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html
If you use GET for a DELETE you are clearly misusing the method according to its standard definition.
Alright so let's further say 'OK but that doesn't really matter because it's just more practical for a developer to read a URI somewhere that uses a GET method and reads /api/entity/delete/{id} instead of having a DELETE method that deletes resources having the same signature as a GET method that retrieves, so that the developer understands that's meant for deletion. Let's consider a well structured DELETE method signature (example is for .NET Core 5):
// DELETE: api/TodoItems/5
[HttpDelete("{id}")]
public async Task<IActionResult> DeleteTodoItem(long id)
{
This will not respond to a get request, (so for example, accidental deletion instead of retrieval when making a call to the API is more protected - the developer has to explicitly perform a DELETE request to the API). And we have a very clear, well structured and named API operation that's clear and highly discoverable by a developer or even automated tooling (e.g. a developer can now search specifically for any occurrence of DELETE in code, or for the method name which clearly indicates the DELETE). And what's more, this pattern conforms to a generally accepted standard for a 'RESTFUL' API that should render the API more broadly recognisable and interpretable to developers (and potentially any automated tooling).
OK, that's nice, but what's the real difference in making it a DELETE? Why even use DELETE instead of GET? My operation is deleting something from the database, why should my web server care? OK, let's think about the definition of DELETE:
9.7 DELETE - The DELETE method requests that the origin server delete the resource identified by the Request-URI. This method MAY be
overridden by human intervention (or other means) on the origin
server.
So now, if we're specifying a delete, we have the potential for specific behaviour on the server that potentially allows for reversing a delete action by manual or automatic intervention. In a particular use case, that could be significant.
OK well DELETE works for me then, but why use PUT? For example it's more convenient if I just make an 'upsert' method that uses POST, and update the resource if it exists or create it if it doesn't
I personally typically do this when I"m implementing an API that effects operations against a database, although again there is specific meaning to PUT i.e. that it specifically indicates updating of a resource, while POST indicates creation, so using POST for both creating and updating is counter-standard. My own view is that a REST API is a case when I typically view the practicality of upsert functionality as being more important that strict use of the correct verb for adds versus insert, but I could be missing something here.
Use of PUT outside of a REST api could be more significant for practical purposes, for example if we're performing an update operation where the server can potentially clear any cacheing by understanding that the resource has been updated (which is more significant if our resource is a whole document, for example). There may be some practical advantages I haven't considered when PUT is utilised inside a restful API for an update operation.
The standard definition for POST states that a POST success response SHOULD be 201 (created), and not just the generic '200 OK', so that we're able to correctly interpret that resource creation is explicitly successful. That response isn't appropriate for an update operation but there's no 'MUST' specified in the standard for the response code. It's certainly common for developers to use POST for an upsert and return 200 (OK) on success, whether it's a creation or an update.
The standard for PUT is more strict, and specifies that any unexpected creation of a resource when attempting an update MUST be indicated via a 201 response code. This can occur if no existing resource exists at the specified URI. The standard explains that if we use PUT we get clearer feedback on whether the result of our attempted update operation is what we expected.
From the W3C standard:
[if a put] 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. If a
new resource is created, the origin server MUST inform the user agent
via the 201 (Created) response. If an existing resource is modified,
either the 200 (OK) or 204 (No Content) response codes SHOULD be sent
to indicate successful completion of the request.
PUT
The PUT method is used whenever you need to change the resource. The resource, which is already a part of resource collection. One thing to note here is that PUT method modifies the entire resource whereas PATCH method is used to modify the necessary part of the resource or data.
DELETE
As the name says, the DELETE request method is used to delete the specified resource. It requests that the origin server delete the resource identified by the Request-URL.
I hope this simple definitions help.

Is it okay to set a cookie with a HTTP GET request?

This might be a bit of an ethical question, but I'm having quite a discussion in the office about the following issue:
Is it okay to set a cookie with a HTTP GET request? Because whenever a HTTP request changes something in the application, you should use a POST request. HTTP GET should only be used to retrieve data identified by the Request-URI.
In this case, the application doesn't change, but because the cookie is altered, the user might get a different experience when the page loads again, meaning that the HTTP GET request changed the application behaviour (nothing changed server-side though).
Get request reference
The discussion started because we want to use a normal anchor element to set a cookie.
The problem with GETs, especially if they are on an a tag, is when they get spidered by the likes of Google.
In your case, you'd needlessly be creating cookies that will, more than likely, never get used.
I'd also argue that the GET rule it's not really about changing the application, more about changing data. I appreciate the subtle distinction with the cookie ( i.e. you are not changing data on YOUR system ), but generally, it's a good rule to have, and irrespective of where the data is stored, GET shouldn't really be used to change it.
The user can always have different experience when he issues another GET request - you do not expect to return always the same set of data for (imagined) time service: "GET /time/current".
Also, it is not said you are not allowed to change server-side state in response for GET requests - it's perfectly 'legal' to increase a page hit counter, for example, even if you store it in the database.
Consider the section 9.1.1 Safe Methods
Naturally, it is not possible to ensure that the server does not
generate side-effects as a result of performing a GET request; in
fact, some dynamic resources consider that a feature. The important
distinction here is that the user did not request the side-effects, so
therefore cannot be held accountable for them.
Also I would say it is perfectly acceptable to change or set a cookie in response for the GET request because you just return some data.

What is the difference between REST and HTTP protocols?

What is the REST protocol and what does it differ from HTTP protocol ?
REST is a design style for protocols, it was developed by Roy Fielding in his PhD dissertation and formalised the approach behind HTTP/1.0, finding what worked well with it, and then using this more structured understanding of it to influence the design of HTTP/1.1. So, while it was after-the-fact in a lot of ways, REST is the design style behind HTTP.
Fielding's dissertation can be found at http://www.ics.uci.edu/~fielding/pubs/dissertation/top.htm and is very much worth reading, and also very readable. PhD dissertations can be pretty hard-going, but this one is wonderfully well-described and very readable to those of us without a comparable level of Computer Science. It helps that REST itself is pretty simple; it's one of those things that are obvious after someone else has come up with it. (It also for that matter encapsulates a lot of things that older web developers learnt themselves the hard way in one simple style, which made reading it a major "a ha!" moment for many).
Other application-level protocols as well as HTTP can also use REST, but HTTP is the classic example.
Because HTTP uses REST, all uses of HTTP are using a REST system. The description of a web application or service as RESTful or non-RESTful relates to whether it takes advantage of REST or works against it.
The classic example of a RESTful system is a "plain" website without cookies (cookies aren't always counter to REST, but they can be): Client state is changed by the user clicking a link which loads another page, or doing GET form queries which brings results. POST form queries can change both server and client state (the server does something on the basis of the POST, and then sends a hypertext document that describes the new state). URIs describe resources, but the entity (document) describing it may differ according to content-type or language preferred by the user. Finally, it's always been possible for browsers to update the page itself through PUT and DELETE though this has never been very common and if anything is less so now.
The classic example of a non-RESTful system using HTTP is something which treats HTTP as if it was a transport protocol, and with every request sends a POST of data to the same URI which is then acted upon in an RPC-like manner, possibly with the connection itself having shared state.
A RESTful computer-readable (i.e. not a website in a browser, but something used programmatically) system would obtain information about the resources concerned by GETting URI which would then return a document (e.g. in XML, but not necessarily) which would describe the state of the resource, including URIs to related resources (hypermedia therefore), change their state through PUTting entities describing the new state or DELETEing them, and have other actions performed by POSTing.
Key advantages are:
Scalability: The lack of shared state makes for a much more scalable system (demonstrated to me massively when I removed all use of session state from a heavily hit website, while I was expecting it to give a bit of extra performance, even a long-time anti-session advocate like myself was blown-away by the massive gain from removing what had been pretty slim use of sessions, it wasn't even why I had been removing them!)
Simplicity: There are a few different ways in which REST is simpler than more RPC-like models, in particular there are only a few "verbs" that are ever possible, and each type of resource can be reasoned about in reasonable isolation to the others.
Lightweight Entities: More RPC-like models tend to end up with a lot of data in the entities sent both ways just to reflect the RPC-like model. This isn't needed. Indeed, sometimes a simple plain-text document is all that is really needed in a given case, in which case with REST, that's all we would need to send (though this would be an "end-result" case only, since plain-text doesn't link to related resources). Another classic example is a request to obtain an image file, RPC-like models generally have to wrap it in another format, and perhaps encode it in some way to let it sit within the parent format (e.g. if the RPC-like model uses XML, the image will need to be base-64'd or similar to fit into valid XML). A RESTful model would just transmit the file the same as it does to a browser.
Human Readable Results: Not necessarily so, but it is often easy to build a RESTful webservice where the results are relatively easy to read, which aids debugging and development no end. I've even built one where an XSLT meant that the entire thing could be used by humans as a (relatively crude) website, though it wasn't primarily for human-use (essentially, the XSLT served as a client to present it to users, it wasn't even in the spec, just done to make my own development easier!).
Looser binding between server and client: Leads to easier later development or moves in how the system is hosted. Indeed, if you keep to the hypertext model, you can change the entire structure, including moving from single-host to multiple hosts for different services, without changing client code at all.
Caching: For the GET operations where the client obtains information about the state of a resource, standard HTTP caching mechanisms allow both for statements that the resource won't meaningfully change until a certain date at the earliest (no need to query at all until then) or that it hasn't changed since the last query (send a couple hundred bytes of headers saying this rather than several kilobytes of data). The improvement in performance can be immense (big enough to move the performance of something from the point where it is impractical to use to the point where performance is no longer a concern, in some cases).
Availability of toolkits: Because it works at a relatively simple level, if you have a webserver you can build a RESTful system's server and if you have any sort of HTTP client API (XHR in browser javascript, HttpWebRequest in .NET, etc) you can build a RESTful system's client.
Resiliance: In particular, the lack of shared state means that a client can die and come back into use without the server knowing, and even the server can die and come back into use without the client knowing. Obviously communications during that period will fail, but once the server is back online things can just continue as they were. This also really simplifies the use of web-farms for redundancy and performance - each server acts like it's the only server there is, and it doesn't matter that its actually only dealing with a fraction of the requests from a given client.
REST is an approach that leverages the HTTP protocol, and is not an alternative to it.
http://en.wikipedia.org/wiki/Representational_State_Transfer
Data is uniquely referenced by URL and can be acted upon using HTTP operations (GET, PUT, POST, DELETE, etc). A wide variety of mime types are supported for the message/response but XML and JSON are the most common.
For example to read data about a customer you could use an HTTP get operation with the URL http://www.example.com/customers/1. If you want to delete that customer, simply use the HTTP delete operation with the same URL.
The Java code below demonstrates how to make a REST call over the HTTP protocol:
String uri =
"http://www.example.com/customers/1";
URL url = new URL(uri);
HttpURLConnection connection =
(HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setRequestProperty("Accept", "application/xml");
JAXBContext jc = JAXBContext.newInstance(Customer.class);
InputStream xml = connection.getInputStream();
Customer customer =
(Customer) jc.createUnmarshaller().unmarshal(xml);
connection.disconnect();
For a Java (JAX-RS) example see:
http://bdoughan.blogspot.com/2010/08/creating-restful-web-service-part-45.html
REST is not a protocol, it is a generalized architecture for describing a stateless, caching client-server distributed-media platform. A REST architecture can be implemented using a number of different communication protocols, though HTTP is by far the most common.
REST is not a protocol, it is a way of exposing your application, mostly done over HTTP.
for example, you want to expose an api of your application that does getClientById
instead of creating a URL
yourapi.com/getClientById?id=4
you can do
yourapi.com/clients/id/4
since you are using a GET method it means that you want to GET data
You take advantage over the HTTP methods: GET/DELETE/PUT
yourapi.com/clients/id/4 can also deal with delete, if you send a delete method and not GET, meaning that you want to dekete the record
All the answers are good.
I hereby add a detailed description of REST and how it uses HTTP.
REST = Representational State Transfer
REST is a set of rules, that when followed, enable you to build a distributed application that has a specific set of desirable constraints.
It is stateless, which means that ideally no connection should be maintained between the client and server.
It is the responsibility of the client to pass its context to the server and then the server can store this context to process the client's further request. For example, session maintained by server is identified by session identifier passed by the client.
Advantages of Statelessness:
Web Services can treat each method calls separately.
Web Services need not maintain the client's previous interaction.
This in turn simplifies application design.
HTTP is itself a stateless protocol unlike TCP and thus RESTful Web Services work seamlessly with the HTTP protocols.
Disadvantages of Statelessness:
One extra layer in the form of heading needs to be added to every request to preserve the client's state.
For security we may need to add a header info to every request.
HTTP Methods supported by REST:
GET: /string/someotherstring:
It is idempotent(means multiple calls should return the same results every time) and should ideally return the same results every time a call is made
PUT:
Same like GET. Idempotent and is used to update resources.
POST: should contain a url and body
Used for creating resources. Multiple calls should ideally return different results and should create multiple products.
DELETE:
Used to delete resources on the server.
HEAD:
The HEAD method is identical to GET except that the server MUST NOT return a message-body in the response. The meta information contained in the HTTP headers in response to a HEAD request SHOULD be identical to the information sent in response to a GET request.
OPTIONS:
This method allows the client to determine the options and/or requirements associated with a resource, or the capabilities of a server, without implying a resource action or initiating a resource retrieval.
HTTP Responses
Go here for all the responses.
Here are a few important ones:
200 - OK
3XX - Additional information needed from the client and url redirection
400 - Bad request
401 - Unauthorized to access
403 - Forbidden
The request was valid, but the server is refusing action. The user might not have the necessary permissions for a resource, or may need an account of some sort.
404 - Not Found
The requested resource could not be found but may be available in the future. Subsequent requests by the client are permissible.
405 - Method Not Allowed
A request method is not supported for the requested resource; for example, a GET request on a form that requires data to be presented via POST, or a PUT request on a read-only resource.
404 - Request not found
500 - Internal Server Failure
502 - Bad Gateway Error

RESTful view counter

I would like to count the access to a resource, but HTTP GET should not modify a resource. The counter should be displayed with the resource. A similar case would be to store the last access.
What is the REST way to realize a view counter?
Updating a counter in reaction to a GET is actually not a violation of the HTTP protocol. You are not modifying the resource you are getting, or any other resource that the client can control.
If a server was not allowed to do any updates in response to a GET then log files would violate the HTTP contract!
Here is the relevant part in RFC2616,:
9.1.1 Safe Methods
Implementors should be aware that the
software represents the user in their
interactions over the Internet, and
should be careful to allow the user to
be aware of any actions they might
take which may have an unexpected
significance to themselves or others.
In particular, the convention has been
established that the GET and HEAD
methods SHOULD NOT have the
significance of taking an action other
than retrieval. These methods ought to
be considered "safe". This allows user
agents to represent other methods,
such as POST, PUT and DELETE, in a
special way, so that the user is made
aware of the fact that a possibly
unsafe action is being requested.
Naturally, it is not possible to
ensure that the server does not
generate side-effects as a result of
performing a GET request; in fact,
some dynamic resources consider that a
feature. The important distinction
here is that the user did not request
the side-effects, so therefore cannot
be held accountable for them.
The first significant thing to note is that it says "SHOULD NOT" and not "MUST NOT". There are cases where side effects are valid.
The second critical line is last line that highlights the fact that the user did not make a request with any desire to make a change and therefore it is up to the server to ensure that nothing happens that would be contradictory to the clients expectations. This is the essence of the "uniform interface constraint". The server should do what the client expects. This is very different than the client issuing
GET /myresource?operation=delete
In this case, the client thinks they are doing a retrieval. If the client application is respecting the hypermedia constraint then the contents of URL are completely opaque, so the only information the client can understand is the verb GET. If the server actually does a delete then, that is a clear violation of the uniform interface constraint.
Updating an internal counter is not a violation of the uniform interface constraint. If the counter was to be included in the representation being retrieved then you have a whole new set of problems, but I am going to assume that is not the case.

Resources