is this REST?

2010-02-17 @ 19:27#

recently, i've been contemplating the details of implementing application flow using REST over HTTP. along the way, i said in the REST IRC channel in freenode that application flows may include multiple resource interactions, some of which may be considered 'interim' resource transitions. IOW, when dealing at the application level (not the HTTP or resource level) there are arcs that involve multiple state transitions.

however, my online friend Jan Algermissen pointed out the use of interim state transitions may actually be a symptom of bad design.

so i have a simple test. below are two implementations of an online survey. i claim both of them are examples of REST-ful implementations. What do you think?

in addition, i have a number of questions at the end of the two examples to see how variations on this theme affect your answers.

a single-question survey

REQUEST ****
GET /surveys/
Host: www.example.org
Accept: application/html

RESPONSE ***
HTTP/1.1 200 OK
Content-Type:application/html

...
<form method="post" action="http://www.example.org/surveys/">
   <label for="name">Name</label>
   <input type="text" name="name" value="" />
   <input type="submit" />
</form>
...

REQUEST ***
POST /surveys/
Host: www.example.org
Content-Type: application/www-form-urlencoded

name=Mike

RESPONSE ***
HTTP/1.1 201 Created
Location: http://www.example.org/surveys/1

...
<a href="http://www.example.org/surveys/1">Begin</a>
...

REQUEST ***
GET /surveys/1
Host: www.example.org
Content-Type: applcation/html

RESPONSE ***
HTTP/1.1 200 OK
Content-Type: application/html

...
<form method="post" action="http://www.example.org/surveys/1">
  <label for"q1">Is this a REST-ful survey?</label>
  <input name="q1" value="" />
  <input type="submit" />
</form>
...

REQUEST ***
POST /surveys/1
Host: www.example.org
Content-Type: application/www-form-urlencoded

q1=yes

RESPONSE ***
HTTP/1.1 200 OK
Content-Type: text/plain

Your survey answer has been recorded. 

a two-question survey

REQUEST ****
GET /surveys/
Host: www.example.org
Accept: application/html

RESPONSE ***
HTTP/1.1 200 OK
Content-Type:application/html

...
<form method="post" action="http://www.example.org/surveys/">
   <label for="name">Name</label>
   <input type="text" name="name" value="" />
   <input type="submit" />
</form>
...

REQUEST ***
POST /surveys/
Host: www.example.org
Content-Type: application/www-form-urlencoded

name=Mike

RESPONSE ***
HTTP/1.1 201 Created
Location: http://www.example.org/surveys/1

...
<a href="http://www.example.org/surveys/1/q1">Begin</a>
...

REQUEST ***
GET /surveys/1/q1
Host: www.example.org
Content-Type: applcation/html

RESPONSE ***
HTTP/1.1 200 OK
Content-Type: application/html

...
<form method="post" action="http://www.example.org/surveys/1/q1">
  <label for"q1">Is this the first question?</label>
  <input name="q1" value="" />
  <input type="submit" />
</form>
...

REQUEST ***
POST /surveys/1/q1
Host: www.example.org
Content-Type: application/www-form-urlencoded

q1=yes

RESPONSE ***
HTTP/1.1 200 OK
Content-Type: application/html

...
<a href="http://www.example.org/surveys/1/q2">Continue</a>
...

REQUEST ***
GET /surveys/1/q2
Host: www.example.org
Content-Type: applcation/html

RESPONSE ***
HTTP/1.1 200 OK
Content-Type: application/html

...
<form method="post" action="http://www.example.org/surveys/1/q2">
  <label for"q2">Is this a REST-ful survey?</label>
  <input name="q2" value="" />
  <input type="submit" />
</form>
...

REQUEST ***
POST /surveys/1/q2
Host: www.example.org
Content-Type: application/www-form-urlencoded

q2=not sure

RESPONSE ***
HTTP/1.1 200 OK
Content-Type: text/plain

Your survey answers have been recorded. 

for your consideration

now consider the following:

  1. how do you create a REST-ful implementation of a survey with 75 questions?
  2. what should be the server response when a client application activates a question out of order (jumps from question #1 to question #13)?
  3. does your answer change if the survey is adaptive? IOW, subsequent questions depend on the answers to previous questions?
  4. how do you create a REST-ful implementation of a timed survey; one in which each question must be answered within a fixed amount of time (60 seconds) and/or the entire survey must be completed within a fixed amount of time (30 minutes)?
  5. how do you create a REST-ful implementation of a survey that allows clients to save their partially-completed work and come back to finish it later?
  6. if a client returns to complete a survey, how does the server make sure the client picks up at the same place they left off?
  7. what if the user wants to complete the survey from a new location (home instead of office)?

code