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!

38 comments:

Unknown 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.

Unknown 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.

Pastor Cmentarny 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.

Anonymous said...
This comment has been removed by the author.
zeekster said...

A good resource

Unknown 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.

madeinindia said...

simply and very lucid to follow

thank you

Unknown said...

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

Well done!

Shailu said...

Wonderful explanation and nice artice .. many thanks

Unknown 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!!

Unknown 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"));

Unknown said...

Brilliant explanation! Thank you!

Unknown said...

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

Lotus Eyes said...

This is a very useful site. As others have mentioned, the examples are simple and very beautifully explained.
Even someone who does not know much about Web services (SOAP or otherwise) can get the hang of them.

Thanks a lot, Dr. Elkstein. I would highly recommend your site to everyone.

- Lakshmi

JK said...

"•Despite being simple, REST is fully-featured; there's basically nothing you can do in Web Services that can't be done with a RESTful architecture."

So how do you set up a transactional web service having a secure context to transfer sensitive information that is encrypted with non repudiation and message integrity within the message body without using SOAP?

Please don't say SSL, that is Transport level, not message level.

SOAP and REST are like a big rig and pickup. They are designed for different mission requirements.

Unknown 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?

Dr. M. Elkstein said...

Hello Apurv,

Your Apache server knows the request type (verb) because it's part of the request -- but not part of the URL. For example, if you're developing using Java Servlets, the method called on your servlet class is either doGet, doPost, or doPut (or one of several others), depending on the HTTP verb used in the request. Other languages/systems represent this differently.

rohit_tiwari said...

Elegant and Transparent Tutorial.
Thanks and Keep it up.

Unknown said...

Even after six long years, it was your blog that somewhat clarifies the concept behind the mystery called REST.
People like you are the actual hero's in the programming community.

Thank you so much.

Unknown said...

Thanks. Now I understand more what is REST. :D Now i need to rest. :D

Unknown said...

I'm running a setup with a DJango-based server and an AngularJS-based frontend client. Would it be a good idea to issue authorization tokens(with client IP and digital signatures) to the clients(once they have given correct login credentials), store the tokens in a database on the server-side, and then have clients send their token along with their requests, or is there a better way?

Dr. M. Elkstein said...

Hi Sumeet,

Yes, this sounds like a reasonable implementation. Of course, depending on the sensitivity of your website, you should probably consider using HTTPS so the token itself can't be copied easily.

Unknown said...

I like the article, simple and now everything is clear for me.
thank you very much..

Unknown said...

"POST can also be used for read-only queries, as noted above, when complex parameters are required."

Why should I use GET at all?

Subodh Kr. said...

Best article I ever read on ReST API. Thanx.

Dr. M. Elkstein said...

Hello Christian Meyer,

GET is useful because it's so easy to work with and manipulate -- you can simply issue commands (requests) from your browser's URL inputbox. For simple stuff, it's more than enough.

Most servers can be easily programmer to accept and handle both kinds of requests equally, so there's no harm in supporting both.