Non-idempotent but safe transition in the REST architecture - web-services

Can you please provide an example of a RESTful API call (using HTTP protocol) which is non-idempotent and safe, at the same time (does something like that even exist)?
To elaborate a little bit on this, while reading about the Hypermedia-Oriented Design, I've encountered the 4 affordance aspects that describe each transition: safety, idempotence, mutability and transclusion. Also, I've encountered a table which describes the HTTP verbs through those aspects and it goes like this:
---------------------------------
HTTP Method Idempotent Safe
---------------------------------
OPTIONS yes yes
GET yes yes
HEAD yes yes
PUT yes no
POST no no
DELETE yes no
PATCH no no
---------------------------------
My intuition tells me that all of the safe methods are automatically idempotent too (but not vice versa). I would just like to either confirm or refute this once and for all.
Thanks in advance for the answers.

A safe method - one that does not modify anything - is by definition idempotent. Since it has not changed anything, it will have the same effect (that is, no effect whatsoever) no matter how many times you call it.

Yes. All safe methods are also idempotent, but they refer to two different (but related) qualities of a RESTful API.
A safe method call (one which does not modify the state of the resource on the server) may be issued multiple times by the client without affecting the state of the server (the definition of idempotency).

Related

DELETE operation in GET rest service

I got a query while developing rest service.
As per the REST design, GET is to read , PUT or POST are to create or update based on scenario , DELETE is to delete the resources.
But technically, Can't we perform a create or delete operation in GET call.
i.e. It is up to client way of calling by using specified URL pattern and required response type to hit the exact method in the service class of REST application. But why can't we perform a delete or create of some data in the GET service.
so my question is the DELETE or CREATE technically not possible in GET service or is it a rule to adhere to REST principles.
so my question is the DELETE or CREATE technically not possible in GET service or is it a rule to adhere to REST principles.
The latter. It is only a convention to use the DELETE HTTP method for delete operations. However using the GET HTTP method for delete operations is a bad idea. Below is a quote from "RESTful Java with JAX-RS 2.0, 2nd Edition" that explains why:
It is crucial that we do not assign
functionality to an HTTP method that supersedes the specification-defined boundaries
of that method. For example, an HTTP GET on a particular resource should be readonly.
It should not change the state of the resource it is invoking on. Intermediate services
like a proxy-cache, a CDN (Akamai), or your browser rely on you to follow the semantics
of HTTP strictly so that they can perform built-in tasks like caching effectively. If you
do not follow the definition of each HTTP method strictly, clients and administration
tools cannot make assumptions about your services, and your system becomes more
complex
so my question is the DELETE or CREATE technically not possible in GET
service or is it a rule to adhere to REST principles?
REST uses standards aka. uniform interface constraint. One of these standards is the HTTP standards which defines the HTTP methods. According to the HTTP standard the GET is a safe method:
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.
According to the RFC 2119:
SHOULD NOT - This phrase, or the phrase "NOT RECOMMENDED" mean that there may exist valid reasons in particular circumstances when the particular behavior is acceptable or even useful, but the full implications should be understood and the case carefully weighed before implementing any behavior described with this label.
For example write can be a side effect by GET, if you want to increase the visitor count by each request.
How the server software (API) is constructed and what 'rules' are applied is somewhat 'arbitrary'. Developers and their product managers could enforce 'rules' such as 'thou shalt not code or support DELETE operations through the GET operation', but in practice, that is not necessarily the main reason POST is chosen over GET. As others have mentioned, there may be assumptions based on the HTTP protocol that other vendors may rely on, but that is a rather complex and not necessarily relevant reasoning. For instance, your application may be built to connect directly to a server application, and another vendor's rules may not apply.
In a simpler example, on the world wide web and due to compliance and other factors, query string has a limited byte length. Because of this, operations that require a lot of data, such as a few very long encrypted data strings that might be needed for a DELETE operation in a database, GET may not be able to pass enough data, so POST may be the only viable option.
Custom built applications using a CuRL library might extend to include other RESTful operations with their intended functionality, but that would be for the benefit of the server API. Coding more operations on the client-side doesn't necessarily make things 'easier', 'faster', or necessarily 'more secure' from the client perspective, but doing so could help manage resources (a bit) on the server side and help maintain compatibility with third party software and appliances.

Alternative approach to sending a lot of parameter data on GET

I am creating a REST-API and am encountering a problem where the client needs to get a calculation based on a lot of different parameters.
This GET operation might not be a part of any Save or Update operations (before the GET or after), and can happen in a stateless manner.
Due to this the GET URL can be very long (and even exceed the maximum allowed by the browser).
I have looked in other posts here in SO and elsewhere and it is discouraged to use a body in GET requests. But whats most important about all these posts is that none of them give an alternative to this problem they just state that something is flawed in the design ETC...ETC...
Well nothing is wrong with the design here. its a stateless calculation built on a lot of parameters.
I would like some alternatives. Thank you.
nothing is wrong with the design here
There is. From Wiki:
An important concept in REST is the existence of resources (sources of specific information), each of which is referenced with a global identifier (e.g., a URI in HTTP).
Your calculation parameters have nothing to do with the underlying resource identified by the URL you make the request to. You're not requesting an existing resource (as that's what GET is for, depending on how you're willing to interpret REST), but some calculations will be done based on some input. This is a Remote Procedure Call, not a REST call.
You can change your approach by modeling a Calculation, so you send a POST /Calculations/ request with all your parameters.
There's no requirement for a POST call to change server state (i.e. store the results):
httpbis-draft, POST (which is somewhat better worded and updated than RFC 2616):
The POST method requests that the target resource process the
representation enclosed in the request according to the resource's
own specific semantics.
POST is used for (among others): providing a block of data, such as the fields entered into an HTML
form, to a data-handling process;
So you can just return the calculation results along with a 200, or you can store them and return a 200, 201 or 204, containing or pointing to the calculation results, so you can retrieve them later, using GET /Calculations/$id.
As far as I can tell, the only solution you have left is to break the rules of REST and use a POST request. POST can have an arbitrary number of arguments, but it's meant for a "modification" operation in REST.
Like everything in software, the rules are there to help you avoid mistakes. But if the rules prevent you from solving your problems, you need to modify them a little bit (or modify them for a well defined part of your code).
Just make sure that everyone understands how you changed the rules, where the new rules apply (and where they don't). Otherwise, the next guy will "fix" your "broken" code with his simple test cases.
So you want a safe HTTP method that accepts a payload. Have a look at http://greenbytes.de/tech/webdav/draft-ietf-httpbis-method-registrations-14.html - both SEARCH and REPORT are theoretical candidates, if you can live with the WebDAV baggage they come with.
An alternative would be to start work on either generalizing these, or defining something new (but don't forget that definitions of new HTTP methods need IETF review, see http://greenbytes.de/tech/webdav/draft-ietf-httpbis-p2-semantics-25.html#considerations.for.new.methods.

Naming convention for asynchronous operations

I have a web service that triggers some long operations on the server via asynchronous methods. Each operation has 3 methods:
One of them start the operation and immediately returns a ticket number.
One of them is called continuously from the client; it receives the ticket number and returns a boolean value, saying whether the operation is done.
The last one of them is called only after the operation is finished; it receives the ticket number and returns the result of the operation.
I'm not sure how to call this methods. I think about calling the methods something like this:
OperationName_Start
OperationName_IsReady
OperationName_GetResult
but I'm afraid I could be reinventing the wheel. Is there any well known naming convention for this usage pattern?
Its a shame you couldn't get an answer the first time around. I would strongly suggest reading this SOA Principles Link to gain a better understanding of the principals and importance of web service naming.
It's key to remember to name from the perspective of the consumer and maximise consumability and re-useability. Its also useful to remember that when you invoke a service, your are performing and action on an object i.e. you should have a verb and a noun. Also remember that web services are very very similar to functions in an object oriented language, so its helpful to think of what the code of the function of the web service would look like.
It's helpful to consider scenarios like:
What would happen if i changed the system the web service was calling?
Is there another scenario that could call this service?
How granular should the service be? What are the performance impacts of these decisions?
Without knowing the business context of what you are trying to achieve, we'll assume a basic example of submitting and electronic payment.
In this scenario, you may have:
ElectronicPayment_SendPayment (Note: the use of 'Send' keeping the business context, not the technical context; send could be via email, post, webservice. From your 'Start' example, what are you starting; here, the intent of the service is apparent)
ElectronicPayment_CheckStatus (Note: this is from the consumer's perspective. It's likely that checking processing status is a generic service, that could be seperated into something along the lines of CheckProcessingStatus (TicketNumber tN)
ElectronicPayment_RetrieveReciept (Note: Request/Response pattern with semantic link. Business Context of receipt and payment maintained)
Naming is highly contextual, and the above is not perfect, but hopefully it helps yourself and others who stumble upon this.
From the lack of answers, I assume that apparently there isn't a widely used standard on this issue, so it's OK to roll my own.
I chose to stick with:
OperationName_Start
OperationName_IsReady
OperationName_GetResult

How to check if a Server and Client are in the same concurrency model?

The concurrency model can be either apartment-threaded or multi-threaded
Question:
How to ensure that both the Client and Server are operating from within the same concurrency model?
Sometimes you need to know. Two quick examples:
Performance hit of proxy/stub pairs is a problem
You need to pass around "unmarshallable" data or objects
So, the answer -- if you do need to know:
The server and the client must be designed and implemented to support the same or compatible models. Either one of these scenarios will do:
Both should be MTA, or
Both should be STA, or
The server should be "Both" (supports either)
The Server should be "free-threaded" (but that doesn't buy you anything extra compared to Both, in this scenario)
If you need to know, there's something wrong with your design: the client and server need too much information about one another's internals. Part of the point of client-server is to decouple the two.
That said, then, there is a registry value ThreadingModel.There's an MSDN article on these things as well.

RESTful web services and HTTP verbs

What is the minimum set of HTTP verbs that a server should allow for a web service to be classed as RESTful?
What if my hoster doesn't permit PUT and DELETE?
Is this actually important, can I live happily ever after with just GET and POST ?
Update: Thanks for the answers folks, Roger's answer was probably best because of the link to the Bill Venners and Elliotte Rusty Harold interview. I now get it.
Yes, you can live without PUT and DELETE.
This article tells you why:
http://www.artima.com/lejava/articles/why_put_and_delete.html
While to true RESTafrians this may be heresy, in the real world you do what you can, with what you have. Be as rational as you can and as consistent with your own convention as you can, but you can definitely build a good RESTful system without P and D.
rp
You can also use X-Http-Verb-Override:DELETE inst. of HTTP DELETE. This is also usefull for Silverlight clients who cant change the HTTP verbs and only support GET and POST...
If you just use GET and POST, it's still RESTful. Your web service may only do things which only required GET or POST, so that's fine.
REST allows for breaking protocol convention if the implementations of the protocol are broken (so that the only non-standard things you do are to get around the broken parts of the implementation). So it is allowable within REST to use some other method to represent generally unsupported verbs like DELETE or PUT.
edit: Here is a quote from Fielding, who is the one that created and defined REST:
A REST API should not contain any changes to the communication protocols aside from filling-out or fixing the details of underspecified bits of standard protocols, such as HTTP’s PATCH method or Link header field. Workarounds for broken implementations (such as those browsers stupid enough to believe that HTML defines HTTP’s method set) should be defined separately, or at least in appendices, with an expectation that the workaround will eventually be obsolete. [Failure here implies that the resource interfaces are object-specific, not generic.]
Today's web browsers only handle GETS + POSTS. In Rails, for example, PUTS + DELETES are "faked" through hidden form fields.
Unless your framework has some workaround to "support" PUTS + DELETES, don't worry about them for now.