Best Practice for Errors in RESTful API - php

What are the best practices for returning HTTP status codes in RESTful API? I am using Laravel 4 for my PHP framework.
In the case of an error, should I use
return Response::json('User Exists', 401);
or
include flag for success
return Response::json([
'success' => false,
'data' => 'User Exists'],
401
);
or
use 200 instead of 4xx, relying on success to determine if there is an error
return Response::json([
'success' => false,
'data' => 'User Exists'],
200
);
And in the case of success and there is no need to return any data, do you still return anything?
PHP API Code
public function getCheckUniqueEmail() {
// Check if Email already exist in table 'users'
$uniqueEmail = checkIfEmailExists();
// Return JSON Response
if($uniqueEmail) {
// Validation fail (user exists)
return Response::json('User Exists', 401);
} else {
// Validation success
// - Return anything?
}
}

When you look at the list of available HTTP status codes, you will at some point realize that there are plenty of them, but used alone they cannot really explain an error by itself.
So to answer your question, there are two parts. One is: How can your API communicate the reasons for an error and add useful information that the user of the API (which in most cases is another developer) can read and act upon. You should add as much information as possible, both machine readable and human readable.
The other part: How can HTTP status codes help in distinguish certain error (and success) states?
This latter part is actually harder than one might thing. There are the obvious cases where 404 is used to tell "not found". And 500 for any errors that are server-side.
I wouldn't use status 401, unless I really want to allow the operation to succeed if there are HTTP authentication credentials present. 401 usually triggers a dialog box in the browser, which is bad.
In case of a ressource being unique and already existing, status "409 Conflict" seems appropriate. And if creating a user succeeds, status "201 Created" sounds like a good idea, too.
Note that there are a lot more status codes, some of them related to extensions of the HTTP protocol (like DAV), some completely unstandardized (like status "420 Enhance your calm" from the Twitter API). Have a look at http://en.wikipedia.org/wiki/List_of_HTTP_status_codes to see what has been used so far, and decide whether you want to use something appropriate for your error cases.
From my experience, it is easy to simply pick a status code and use it, but it is hard to do so consistently and in accordance with existing standards.
I wouldn't however stop here just because others might complain. :) Doing RESTful interfaces right is a hard task in itself, but the more interfaces exists, the more experience has been gathered.
Edit:
Regarding versioning: It is considered bad practice to put a version tag into the URL, like so: example.com/api/v1/stuff It will work, but it isn't nice.
But the first thing is: How does your client specify which kind of representation he wants to get, i.e. how can he decide to either get JSON or XML? Answer: With the Accept header. He could send Accept: application/json for JSON and Accept: application/xml for XML. He might even accept multiple types, and it is for the server to decide then what to return.
Unless the server is designed to answer with more than one representation of the resource (JSON or XML, client-selected), there really isn't much choice for the client. But it still is a good thing to have the client send at least "application/json" as his only choice and then return a header Content-type: application/json in response. This way, both sides make themselves clear about what they do expect the other side to see the content like.
Now for the versions. If you put the version into the URL, you effectively create different resources (v1 and v2), but in reality you have only one resource (= URL) with different methods to access it. Creating a new version of an API must take place when there is a breaking change in the parameters of a request and/or the representation in the response which is incompatible with the current version.
So when you create an API that uses JSON, you do not deal with generic JSON. You deal with a concrete JSON structure that is somehow unique to your API. You can and probably should indicate this in the Content-type sent by the server. The "vendor" extension is there for this: Content-type: application/vnd.IAMVENDOR.MYAPI+json will tell the world that the basic data structure is application/json, but it is your company and your API that really tells which structure to expect. And that's exactly where the version for the API request fits in: application/vnd.IAMVENDOR.MYAPI-v1+json.
So instead of putting the version in the URL, you expect the client to send an Accept: application/vnd.IAMVENDOR.MYAPI-v1+json header, and you respond with Content-type: application/vnd.IAMVENDOR.MYAPI-v1+json as well. This really changes nothing for the first version, but let's see how things develop when version 2 comes into play.
The URL approach will create a completely unrelated set of new resources. The client will wonder if example.com/api/v2/stuff is the same resource as example.com/api/v1/stuff. The client might have created some resources with the v1 API and he stored the URLs for this stuff. How is he supposed to upgrade all these resources to v2? The resources really have not changed, they are the same, the only thing that changed is that they look different in v2.
Yes, the server might notify the client by sending a redirect to the v2 URL. But a redirect does not signal that the client also has to upgrade the client part of the API.
When using an accept header with the version, the URL of the resource is the same for all versions. The client decides to request the resource with either version 1 or 2, and the server might be so kind and still answers version 1 requests with version 1 responses, but all version 2 requests with the new and shiny version 2 responses.
If the server is unable to answer to a version 1 request, he can tell the client by sending HTTP status "406 Not Acceptable" (The requested resource is only capable of generating content not acceptable according to the Accept headers sent in the request.)
The client can send the accept header with both versions included, which enabled the server to respond with the one he likes most, i.e. a smart client might implement versions 1 and 2 and now sends both as accept header, and waits for the server to upgrade from version 1 to 2. The server will tell in every response whether it is version 1 or 2, and the client can act accordingly - he does not need to know the exact date of the server version upgrade.
To sum it up: For a very basic API with limited, maybe internal, usage even having a version might be overkill. But you never know if this will be true a year from now. It is always a very good idea to include a version number into an API. And the best spot for this is inside the mime type that your API is about to use. Checking for the single existing version should be trivial, but you have the option of transparently upgrading later, without confusing existing clients.

I wouldn't use 200 status for everything. That just would be confusing.
Jquery allows you to process different response codes differently, there are built in methods for that already so take advantage of using them in your apps and when your app grows you can provide that API for others to use too.
Edit:
Also I highly recommend watching this talk about Laravel and API development:
http://kuzemchak.net/blog/entry/laracon-slides-and-video

There are some list of HTTP Status Code at Illuminate\Http\Response that extend to Symfony\Component\HttpFoundation\Response. You can use that in your class.
For example:
use Illuminate\Http\Response as LaravelResponse;
...
return Response::json('User Exists', LaravelResponse::HTTP_CONFLICT);
It much more readable.

Related

Should Rest API accept POST array or JSON string?

I've been reading a few REST tutorials and some of them says that in order to send data to a rest API you should send post data as an array, which is something like this:
$data = array('foo' => 'bar');
$rest->post($data);
Then there are others that say you should send JSON data like this:
$data = array('foo' => 'bar');
$data = json_encode($data);
$rest->post($data);
Not sure if there's a standard way of doing this or either if is fine but what is generally recommended when designing API's?
EDIT: There seems to be confusion. To clarify I agree JSON should be used for client consumption but this question is about SERVER consumption. Meaning should the SERVER accept JSON or POST data from its clients?
If you're the one creating the RESTful API, meaning your application is the server and is accepting requests, then your question seems confusing. Your application will not be sending any POST data; clients will be sending POST data to you.
With that being said, having an API which will accept JSON-encoded requests is possible, though would really only be useful for very niche scenarios. The vast majority of clients will be POSTing data to your API in the application/x-www-form-urlencoded format. PHP handles this behind the scenes for you, and exposes the data as the $_POST superglobal.
If you're talking about responding to POST requests, and what format you should use, then that will depend on what format the client wants you to send it in. The client will either specify this in the Accept header, or some APIs allow it to be specified in the URL (e.g. foo.com/some/thing/123.json or foo.com/some/thing/123/json). The client isn't required to tell your application what format it wants, so it's up to you to pick a sensible default. Most APIs will use JSON these days.
I've never heard of an API that understood serialized PHP array format, though, so I don't know what resources you've been reading, but I'm pretty sure you misunderstood what they were suggesting.
Actually, I think this is a pretty good question. don't know why it got downvoted.
Also, contrary to what I saw written in some comments, the client can use any language he wants, not only javascript. And it's not the server job to know which language was used to "build" the request, just that the request is valid. This makes more sense if you think that the entity making the request can actually be another server (think about a proxy server used to send post requests across domains).
That being said, personally, I think it's better for the server side to consume a XML or JSON. The main reason is validation.
It's easier to validate a XML or JSON against a schema.
Also the schema can be made public, and a well designed schema can describe webservice by itself. The client can even use the same schema to validate the request prior to sending it to the server.
Passing an url encoded form is also valid, of course. And can be validated server side as well. SO i think, down the road, it's just a matter of preference.
Also, check this discussion in SO, it regards the same topic:
JSON vs Form POST
You should think about the clients that will consume the API. A HTML5\AJAX client will probably want JSON data, while other clients (Silverlight or native mobile apps) might be better at consuming XML.
One great framework\platform for writing REST API's is looking to be Microsoft's Web API (based on ASP.NET MVC). The product succeeds the WCF framework and allows users to write REST API's in a MVC environment. One feature is that it chooses a serialization provider based on the HTTP Accept header.
So if a client Accepts application/json they work with the service in JSON and if the accept XML they work with the service in XML. You can also write your own object serializer and plug it into the framework.
More information: http://www.asp.net/web-api/overview/getting-started-with-aspnet-web-api/video-your-first-web-api
Most of the time you would want to stick to receiving POST data but I think receiving json data does have its uses for example when it comes to batch requests.
The Facebook API uses it.
You don't need to do file_get_contents('php//input'). From the facebook documentation you could just do something like this:
curl -X POST "http://example.com/batch" -d 'batch={ "param" : 1, "param2" : "2"}'
Then in the PHP code, if you're using PHP, you can get it through the $_POST parameter and do a json_decode.
var_dump($_POST);
array(1) {
["batch"]=>
string(30) "{ "param" : 1, "param2" : "2"}"
}
var_dump(json_decode($_POST['batch'], true));
array(2) {
["param"]=>
int(1)
["param2"]=>
string(1) "2"
}
JSON makes more sense, since it is language-independent and can be useful when API scales.
I am currently developing a REST API and I was asking myself the same question. After some research I found out that is no standard and is totally up to you.
You are developing the server side so you can decide how data should be sent to you. The client need to adapt to your design.
Personally I choose to receive all POST and PUT data as JSON directly in body.
The point is to reuse the HTTP implementation that already exists.
HTTP is built to accept many different content-types and you only need to specify which you are using in the headers.
A REST API that accepts the various formats and works off the content-type header is refreshing. You can submit x-www-form-urlencoded values from an HTML webpage or make an AJAX request with raw JSON and there is no confusion as long as everyone is following protocol.
As a developer you must choose the support your app will provide because you can't support everything. Typically it boils down to the support or convenience of your own environment -- nobody wants to reinvent the wheel.
Many frameworks that are designed with building APIs in mind, handle the most popular content types at a lower level. They may also encode the response data according to the "Accept" header.
Implement whatever you think will be used most first or find a framework that already speaks HTTP and takes care of all of that for you.

RESTful API help, confused with HTTP and XML responses

I am writing an API and have been reading tutorials etc from various sources. I am a little confused regarding responses. I have written a class that will send back a HTTP header response as well as an XML response. Is this correct or should I be using one or the other and not both? Also how to do I check the HTTP header response I send is correct? Im using PHP.
I have used the following tool to check the HTTP response:
http://www.seoconsultants.com/tools/check-server-headers-tool/
which says the response is HTTP/1.1 200 OK. However in my script I have set it as:
header(HTTP/1.1 401 Unauthorized);
Therefore which is correct? How can I check properly? Any ideas what is going wrong?
Many thanks in advance for your help.
Redbot http://redbot.org/ will give a very thorough analysis of your HTTP response to ensure you are compliant with the HTTP spec.
You would be well advised to read some introductory material on the HTTP protocol. It will make your life much easier.
In a restful service, you use the http methods get, put, post and delete, so the http header is there "included". The payload of such a method call can be formatted the way you like (it must be an existing mimetype!), so xml is possible, too! You have to divide between the response "metadata" and the response payload: the "metadata" is a http header, the payload is your xml string, so you have to send both! Otherwise, you would send an empty response :-)
In your request you have to define which data representation (in your case xml) should be used for the response. Have a look at this image (the left one ist restful).
But nevertheless it is a good idea to use a framework for this, like other answers say.
Are you writing this from scratch? if you are then use a common or popular framework as basis and concentrate to building your API methods and let the framework handle the delivery mechanism
http://inchoo.net/tools-frameworks/symfony2-rest/ and you can google for more samples
HTTP Headers could be any you like - let the client handle them. Client can use them to find out if the operation (request) finished successfully or not, if the service is available and other common useful stuff. Headers are correct if they are either pre-defined by protocol and contain valid data or they are defined by you (no validations needed).
XML, JSON or any other response is the data you want to tell the client. It may contain details on errors, the results of performed actions and so on.
I don't suggest you mess with the HTTP header response. Keep it always set to 200 OK, and send back the needed information in the XML response.
That way, the client has to worry only about the XML response. In case there was an HTTP error, such as 403 Forbidden, it would mean this is on the system level (sever configuration) rather than on the application layer itself.

Caching data retrieved by jQuery

I am using jQuery's $.ajax method to retrieve some JSON from an API.
Each time the page is loaded, a call to the API is made, regardless if the user has has received this data before - which means when a large amount of users are on the page, the API limiting would come into effect.
My thought of how to deal with this would be firstly pushing the data to a database (pushing to a PHP script), and then checking the database to see if anything is cached, before going back to the API to get more up to date information if required.
Is this a viable method? What are the alternatives?
It just seems like jQuery is actually a hurdle, rather than doing it all in PHP to begin with, but as I'm learning the language, would like to use it as much as I can!
In order to help distinguish between opinions and recommended techniques, lets first break down your problem to make sure everyone understands your scenario.
Let's say we have two servers: 'Server A' and 'Server B'. Call 'Server A' our PHP web server and 'Server B' our API server. I'm assuming you don't have control over the API server which is why you are calling it separately and can't scale the API server in parallel to your demand. Lets say its some third party application like flickr or harvest or something... let's say this third party API server throttles requests per hour by your developer API key effectively limiting you to 150 requests per hour.
When one of your pages loads in the end-users browser, the source is coming from 'Server A' (our php server) and in the body of that page is some nice jQuery that performs an .ajax() call to 'Server B' our API server.
Now your developer API key only allows 150 requests per hour, while hypothetically you might see 1000 requests inside one hours to your 'Server A' PHP server. So how do we handle this discrepancy of loads, given the assumption that we can't simple scale up the API server (the best choice if possible).
Here are a few things you can do in this situation:
Just continue as normal, and when jQuery.ajax() returns a 503 service
unavailable error due to throttling (what most third party APIs do) tell your end user politely that
you are experiencing higher than normal traffic and to try again
later. This is not a bad idea to implement even if you also add in
some caching.
Assuming that data being retrieved by the API is cache-able, you
could run a proxy on your PHP server. This is particularly well
suited when the same ajax request would return the same response
repeatedly over time. (ex: maybe you are fetching some description
for an object, the same object request should return the same description response for
some period of time). This could be a PHP Pass through proxy or a
lower level proxy like SQUID caching proxy. In the case of a PHP Pass through proxy you would use the "save to DB or filesystem" strategy for caching and could even re-write the expires headers to suite your level of desired cache lifetime.
If you have established that the response data is cache-able, you can
allow the client side to also cache the ajax response using
cache:true. jQuery.ajax() actually defaults to having cache:true, so you simply need to not set cache to false for it to be caching responses.
If your response data is small, you might consider caching it client-side in a
cookie. But experience says that most users who clear their temporary
internet files will also clear their cookies. So maybe the built in caching with jQuery.ajax() is just as good?
HTML5 local storage for client-side caching is cool, but lacks wide-spread popular support.
If you control your user-base (such as in a corporate environment) you
may be able to mandate the use of an HTML5 compliant browser. Otherwise, you
will likely need a cookie based fallback or polyfill for browsers lacking
HTML5 local storage. In which case you might just reconsider other options above.
To summarize, you should be able to present the user with a friendly service unavailable message no matter what caching techniques you employ. In addition to this you may employ either or both server-side and client-side caching of your API response to reduce the impact. Server-side caching saves repeated requests to the same resource while client side caching saves repeated requests to the same resources by the same user and browser. Given the scenario described, I'd avoid Html5 LocalStorage because you'll need to support fallback/polyfill options which make the built in request caching just as effective in most scenarios.
As you can see jQuery won't really change this situation for you much either way vs calling the API server from PHP server-side. The same caching techniques could be applied if you performed the API calls in PHP on the server side vs performing the API calls via jQuery.ajax() on the client side. The same friendly service unavailable message should be implemented one way or another for when you are over capacity.
If I've misunderstood your question please feel free to leave a comment and clarify and/or edit your original question.
No, don't do it in PHP. Use HTML5 LocalStorage to cache the first request, then do your checking. If you must support older browsers, use a fallback (try these plugins).

REST API - why use PUT DELETE POST GET?

So, I was looking through some articles on creating REST API's.
And some of them suggest using all types of HTTP requests: like PUT DELETE POST GET.
We would create for example index.php and write API this way:
$method = $_SERVER['REQUEST_METHOD'];
$request = split("/", substr(#$_SERVER['PATH_INFO'], 1));
switch ($method) {
case 'PUT':
....some put action....
break;
case 'POST':
....some post action....
break;
case 'GET':
....some get action....
break;
case 'DELETE':
....some delete action....
break;
}
OK, granted - I don't know much about web services (yet).
But, wouldn't it be easier to just accept JSON object through regular POST or GET (that would contain method name and all parameters) and then respond in JSON as well. We can easily serialize/deserialize via PHP's json_encode() and json_decode() and do whatever we want with that data without having to deal with different HTTP request methods.
Am I missing something?
UPDATE 1:
Ok - after digging through various API's and learning a lot about XML-RPC, JSON-RPC, SOAP, REST I came to a conclusion that this type of API is sound. Actually stack exchange is pretty much using this approach on their sites and I do think that these people know what they are doing Stack Exchange API.
The idea of REpresentational State Transfer is not about accessing data in the simplest way possible.
You suggested using post requests to access JSON, which is a perfectly valid way to access/manipulate data.
REST is a methodology for meaningful access of data. When you see a request in REST, it should immediately be apparant what is happening with the data.
For example:
GET: /cars/make/chevrolet
is likely going to return a list of chevy cars. A good REST api might even incorporate some output options in the querystring like ?output=json or ?output=html which would allow the accessor to decide what format the information should be encoded in.
After a bit of thinking about how to reasonably incorporate data typing into a REST API, I've concluded that the best way to specify the type of data explicitly would be via the already existing file extension such as .js, .json, .html, or .xml. A missing file extension would default to whatever format is default (such as JSON); a file extension that's not supported could return a 501 Not Implemented status code.
Another example:
POST: /cars/
{ make:chevrolet, model:malibu, colors:[red, green, blue, grey] }
is likely going to create a new chevy malibu in the db with the associated colors. I say likely as the REST api does not need to be directly related to the database structure. It is just a masking interface so that the true data is protected (think of it like accessors and mutators for a database structure).
Now we need to move onto the issue of idempotence. Usually REST implements CRUD over HTTP. HTTP uses GET, PUT, POST and DELETE for the requests.
A very simplistic implementation of REST could use the following CRUD mapping:
Create -> Post
Read -> Get
Update -> Put
Delete -> Delete
There is an issue with this implementation: Post is defined as a non-idempotent method. This means that subsequent calls of the same Post method will result in different server states. Get, Put, and Delete, are idempotent; which means that calling them multiple times should result in an identical server state.
This means that a request such as:
Delete: /cars/oldest
could actually be implemented as:
Post: /cars/oldest?action=delete
Whereas
Delete: /cars/id/123456
will result in the same server state if you call it once, or if you call it 1000 times.
A better way of handling the removal of the oldest item would be to request:
Get: /cars/oldest
and use the ID from the resulting data to make a delete request:
Delete: /cars/id/[oldest id]
An issue with this method would be if another /cars item was added between when /oldest was requested and when the delete was issued.
This is a security and maintainability question.
safe methods
Whenever possible, you should use 'safe' (unidirectional) methods such as GET and HEAD in order to limit potential vulnerability.
idempotent methods
Whenever possible, you should use 'idempotent' methods such as GET, HEAD, PUT and DELETE, which can't have side effects and are therefore less error prone/easier to control.
Source
In short, REST emphasizes nouns over verbs. As your API becomes more complex, you add more things, rather than more commands.
You asked:
wouldn't it be easier to just accept JSON object through normal $_POST and then respond in JSON as well
From the Wikipedia on REST:
RESTful applications maximize the use of the pre-existing, well-defined interface and other built-in capabilities provided by the chosen network protocol, and minimize the addition of new application-specific features on top of it
From what (little) I've seen, I believe this is usually accomplished by maximizing the use of existing HTTP verbs, and designing a URL scheme for your service that is as powerful and self-evident as possible.
Custom data protocols (even if they are built on top of standard ones, such as SOAP or JSON) are discouraged, and should be minimized to best conform to the REST ideology.
SOAP RPC over HTTP, on the other hand, encourages each application designer to define a new and arbitrary vocabulary of nouns and verbs (for example getUsers(), savePurchaseOrder(...)), usually overlaid onto the HTTP 'POST' verb. This disregards many of HTTP's existing capabilities such as authentication, caching and content type negotiation, and may leave the application designer re-inventing many of these features within the new vocabulary.
The actual objects you are working with can be in any format. The idea is to reuse as much of HTTP as possible to expose your operations the user wants to perform on those resource (queries, state management/mutation, deletion).
You asked:
Am I missing something?
There is a lot more to know about REST and the URI syntax/HTTP verbs themselves. For example, some of the verbs are idempotent, others aren't. I didn't see anything about this in your question, so I didn't bother trying to dive into it. The other answers and Wikipedia both have a lot of good information.
Also, there is a lot to learn about the various network technologies built on top of HTTP that you can take advantage of if you're using a truly restful API. I'd start with authentication.
In regards to using extension to define data type.
I noticed that MailChimp API is doing it, but I don't think this is a good idea.
GET /zzz/cars.json/1
GET /zzz/cars.xml/1
My sound like a good idea, but I think "older" approach is better - using HTTP headers
GET /xxx/cars/1
Accept: application/json
Also HTTP headers are much better for cross data type communication (if ever someone would need it)
POST /zzz/cars
Content-Type: application/xml <--- indicates we sent XML to server
Accept: application/json <--- indicates we want get data back in JSON format
Am I missing something?
Yes. ;-)
This phenomenon exists because of the uniform interface constraint. REST likes using already existing standards instead of reinventing the wheel. The HTTP standard has already proven to be highly scalable (the web is working for a while). Why should we fix something which is not broken?!
note: The uniform interface constraint is important if you want to decouple the clients from the service. It is similar to defining interfaces for classes in order to decouple them from each other. Ofc. in here the uniform interface consists of standards like HTTP, MIME types, URI, RDF, linked data vocabs, hydra vocab, etc...
Good Semantics is important in programming.
Utilizing more methods besides GET/POST will be helpful because it will increase the readability of your code and make it easier to maintain.
Why?
Because you know GET will retrieve data from your api. You know POST will add new data to your system. You know PUT will make updates. DELETE will delete rows etc, etc,
I normally structure my RESTFUL Web Services so that I have a function callback named the same thing as the method.
I use PHP, so I use function_exists (I think its called). If the function doesn't exist, I throw a 405 (METHOD NOT ALLOWED).
Bill Venners: In your blog post entitled "Why REST Failed," you said that we need all four HTTP verbs—GET, POST, PUT, and DELETE— and lamented that browser vendors only GET and POST." Why do we need all four verbs? Why aren't GET and POST enough?
Elliotte Rusty Harold: There are four basic methods in HTTP: GET, POST, PUT, and DELETE. GET is used most of the time. It is used for anything that's safe, that doesn't cause any side effects. GET is able to be bookmarked, cached, linked to, passed through a proxy server. It is a very powerful operation, a very useful operation.
POST by contrast is perhaps the most powerful operation. It can do anything. There are no limits as to what can happen, and as a result, you have to be very careful with it. You don't bookmark it. You don't cache it. You don't pre-fetch it. You don't do anything with a POST without asking the user. Do you want to do this? If the user presses the button, you can POST some content. But you're not going to look at all the buttons on a page, and start randomly pressing them. By contrast browsers might look at all the links on the page and pre-fetch them, or pre-fetch the ones they think are most likely to be followed next. And in fact some browsers and Firefox extensions and various other tools have tried to do that at one point or another.
PUT and DELETE are in the middle between GET and POST. The difference between PUT or DELETE and POST is that PUT and DELETE are *idempotent, whereas POST is not. PUT and DELETE can be repeated if necessary. Let's say you're trying to upload a new page to a site. Say you want to create a new page at http://www.example.com/foo.html, so you type your content and you PUT it at that URL. The server creates that page at that URL that you supply. Now, let's suppose for some reason your network connection goes down. You aren't sure, did the request get through or not? Maybe the network is slow. Maybe there was a proxy server problem. So it's perfectly OK to try it again, or again—as many times as you like. Because PUTTING the same document to the same URL ten times won't be any different than putting it once. The same is true for DELETE. You can DELETE something ten times, and that's the same as deleting it once.
By contrast, POST, may cause something different to happen each time. Imagine you are checking out of an online store by pressing the buy button. If you send that POST request again, you could end up buying everything in your cart a second time. If you send it again, you've bought it a third time. That's why browsers have to be very careful about repeating POST operations without explicit user consent, because POST may cause two things to happen if you do it twice, three things if you do it three times. With PUT and DELETE, there's a big difference between zero requests and one, but there's no difference between one request and ten.
Please visit the url for more details. http://www.artima.com/lejava/articles/why_put_and_delete.html
Update:
Idempotent methods
An idempotent HTTP method is a HTTP method that can be called many times without different outcomes. It would not matter if the method is called only once, or ten times over. The result should be the same. Again, this only applies to the result, not the resource itself. This still can be manipulated (like an update-timestamp, provided this information is not shared in the (current) resource representation.
Consider the following examples:
a = 4;
a++;
The first example is idempotent: no matter how many times we execute this statement, a will always be 4. The second example is not idempotent. Executing this 10 times will result in a different outcome as when running 5 times. Since both examples are changing the value of a, both are non-safe methods.
Basically REST is (wiki):
Client–server architecture
Statelessness
Cacheability
Layered system
Code on demand (optional)
Uniform interface
REST is not protocol, it is principles.
Different uris and methods - somebody so called best practices.

Open Id XRDS Discovery

I am working with Open Id, just playing around making a class to interact / auth Open Id's on my site (in PHP). I know there are a few other Libraries (like RPX), but I want to use my own (its good to keep help better understand the protocol and whether its right for me).
The question I have relates to the Open Id discovery sequence. Basically I have reached the point where I am looking at using the XRDS doc to get the local identity (openid.identity) from the claimed identity (openid.claimed_id).
My question is, do I have to make a cURL request to get the XRDS Location (X-XRDS-location) and then make another cURL request to get the actual XRDS doc??
It seems like with a DUMB request I only make one cURL request and get the Open Id Server, but have to make two to use the XRDS Smart method. Just doesn't seem right, can anyone else give me some info.
To be complete, yes, your RP must HTTP GET on the URL the user gives you, and then search for an XRDS document reference and if found do another HTTP GET from there. Keep in mind that the XRDS may be hosted on a different server, so don't code up anything that would require the connection to be the same between the two requests since it might not be the same connection.
If in your initial HTTP GET request you include the HTTP header:
Accept: application/xrds+xml
Then the page MAY respond immediately with the XRDS document rather than an HTML document that you have to parse for an XRDS link. You'll be able to detect that this has occurred by checking the HTTP response header for application/xrds+xml in its Content-Type header. This is an optimization so that RPs don't typically have to make that second HTTP GET call -- but you can't rely on it happening.
The best advice I can give you, is to try to abstract your HTTP requesting a little bit, and then just go through the entire process of doing an HTTP request twice.
You can keep your curl instances around if you want to speed things up using persistent connections, but that may or may not be want you want.
I hope this helps, and good luck.. OpenID is one of the most bulky and convoluted web standards I've come across since WebDAV =)
Evert
I know I'm late to the game here, but I think you should also check out the webfinger protocol. It takes the standard "email as userid" pattern and lets you do a lookup from there to discover openid etc.

Categories