4. More Complex REST Requests

The previous section included a simple example for a REST request -- with a single parameter.

REST can easily handle more complex requests, including multiple parameters. In most cases, you'll just use HTTP GET parameters in the URL.

For example:

http://www.acme.com/phonebook/UserDetails?firstName=John&lastName=Doe

If you need to pass long parameters, or binary ones, you'd normally use HTTP POST requests, and include the parameters in the POST body.

As a rule, GET requests should be for read-only queries; they should not change the state of the server and its data. For creation, updating, and deleting data, use POST requests. (POST can also be used for read-only queries, as noted above, when complex parameters are required.)

  • In a way, this web page (like most others) can be viewed as offering services via a REST API; you use a GET request to read data, and a POST request to post a comment -- where more and longer parameters are required.

While REST services might use XML in their responses (as one way of organizing structured data), REST requests rarely use XML. As shown above, in most cases, request parameters are simple, and there is no need for the overhead of XML.

  • One advantage of using XML is type safety. However, in a stateless system like REST, you should always verify the validity of your input, XML or otherwise!

26 comments:

Mangol said...

>REST stands for Representational State Transfer. (It is sometimes spelled "ReST".) It relies on a stateless, client-server, cacheable communications protocol



>One advantage of using XML is type safety. However, in a stateless system like REST, you should always verify the validity of your input, XML or otherwise!


What does "stateless" system mean?

Dr. M. Elkstein said...

Hi Mangol,

Generally speaking, "stateless" means the server does not maintain state information per-client. For a simple example, consider a file-reading service. One possible API is of the kind common in most programming languages, with functions like FileOpen and FileRead, that can be used like this:

File f = FileOpen("myfile.dat");
byte[] firstK = FileRead(f, 1024);
byte[] secondK = FileRead(f, 1024);

In this pseudo-code, firstK will contain the first 1,024 bytes, and secondK will contain the next 1,024 bytes. But note how both were created using the exact same function call, with the exact same argument list! This happens because the system "remembers", for each open file, where is the "file read head"; this is the state, in this case.

By comparison, a stateless API can be used to achieve the same results, like this (again in pseudo-code):

firstK = FileRead("myfile.dat", 0, 1024);
secondK = FileRead("myfile.dat", 1024, 1024);

Here, the FileRead function accepts the filename, where to start, and the amount to read; there is no "state" associated with the file, and invoking the exact same command twice will yield the exact same result (assuming the file itself was not chagned, of course).

Clearly, stateless APIs make little sense for local file-reading functions; but they do make a lot of sense in a web-based API. The three key benefits are:

(a) Surviving a server restart. If the server had to remember per-client state, a restart would mean all the state data is lost. But with a stateless server, clients don't care if the server was rebooted.

(b) No client-to-server binding; the requests can be handled by a cluster of servers, and each request can be handled by a different machine in the cluster (no "server affinity" for the clients). In a stateful API, either the exact same machine has to handle all requests by the same client, or else the state of all clients must be replicated across all servers.

(c) Increased scalability. In HTTP, the server never knows if and when the client will issue the next request. Maintaining state for numerous clients can impose a strain on server resources (mainly memory), and stateful systems use a time-out mechanism to end sessions where the clients take too much time between requests. There's no such problem if the server is stateless.

thethinker said...

Is a true Stateless server possible? Even for authentication with a token mechanism, the server needs to remember atleast the credentials. So, the timeout and expiry in such a case is still applicable. Also, these credentials needs to be shared between servers in a scaled architecture. Could you please throw some light on how this is taken care of?

Dr. M. Elkstein said...

Hi "thethinker",

There are several ways to do that... One is to introduce state just for login credentials, as you noted. Another is have a smart-token: something that includes the username, an expiration timestamp, and a digital signature of both, for example -- so it can be verified by the server, statelessly.

For multi-server setups, server affinity (by IP, or using cookies) is sometimes used. Of course, the cookie-based approach might fail for REST, since many clients are not browsers and will not respect cookie requests. Other than that, either of the two options presented above (shared storage for user state data or signed tokens) could work.

Raj said...

Simple and beautiful article

Dave Horne said...

Great and Simple Examples. I was looking for a basic understanding of what REST is and the URI example versus the SOAP package, plus the envelope and postcard are the best examples I've seen. I read another article for 30 minutes; and still didn't have a clear understanding of the difference or its purpose; with this; I understood it in 3 minutes.

Thank you.

CESabarre said...

Great Tutorial! Thank you for creating this site.

Atiqur Sumon said...

What an Idea Thank you. Your tutorial so much helpful

RP said...

Thanks so much for this simple article. It went a long way in answering my questions. I just had a real world question. I am building a RESTFul service at my end and this is for remote clients and partners of ours to use. If I have a set of complex parameters that I am expecting say for e.g.: One of my POST methods requires me to save a complete User information like fname, lname, zip, address1 etc. I can easily create a .NET class called User, with all these attributes becoming fields of that class and my POST method can expect a parameter called: private void CreateUser(User u). BUT how can I advise my remote partners to use the User class and how would they know about the User class If I don't give them that. Basically, my question is, how do I send complex objects as parameters to my LOST method If I am just writing the service and not writing the client.. Thanks in advance!!

RP said...

I meant POST and not LOST..

Dr. M. Elkstein said...

Thanks for the question, RP. I've posted a new entry in the FAQ that might be helpful here.

Dominik Symonowicz said...

Your tutorial is awesome piece of work.THANK YOU for your effort.

Good job!

Unknown said...

I like your article. Thanks!

As for RP's question, I think it can be resolved by JSON. JSON can be used to pack your object data and can restore the object from the pack. That's Json's serialization and deserialization. You don't have to write them by yourself. Most frameworks have such built-in features.

ken said...
This comment has been removed by the author.
ken said...

why this, http://www.acme.com/phonebook/UserDetails/12345, is treated as RESTful style? I meant, for example, when my Apache server receives this, how the server knows the request is GET, POST or PUT?

zeekster said...

A good resource

Benj Mikko Adrian Tupas said...

Thanks, Dr. Elkstein. Very clear article.

Bharat Prasad Satyal said...

How to request rest service with xml file. Actually i need to request service which requires basic authentication. for e.g. crowd rest api.

Dr. M. Elkstein said...

Hi Bharat,

For authentication, see the discussion in the FAQ: http://rest.elkstein.org/2008/01/how-do-i-handle-authentication-in-rest.html

As for requesting XML documents -- identical to requesting JSON or HTML documents; a standard HTTP request. The returned document type is the server's decision.

Abuzar said...

simply and very lucid to follow

thank you

Rick Scheck said...

"Everything should be made as simple as possible, but not simpler."

Well done!

Shailu said...

Wonderful explanation and nice artice .. many thanks

Frank D. said...

Dr M. Elkstein..Please write a book about REST,..lots of book out there are wasting of our time.Do this Please so we can reward you with your knowledge that way it will also be easy to pass that knoweledge for generations to come.Great Teachers are rare to find...you are a diamond in a wildness!!

Muhammed Refaat said...

a great work, but there's something i couldn't get, when trying the post action it works so well but when coming to post it gives me a 404 not found, i'm leaving the function as it is and assigning the parameters that passes to it, for example:

$resp = httpRequest("http://wordpress.org/",
80, "POST", "/support/topic/junk-after-document-element-breaking-feed",
array("replies" => "3"));

Miguel Martinez said...

Brilliant explanation! Thank you!

Mbokicommsystem.net said...

Thank you very much! The Letter vs PostCard example really takes the point home