[Catalyst] Re: REST - like uri design for CRUD

Pedro Melo melo at simplicidade.org
Fri Jan 25 22:37:43 GMT 2008


Hi,

On Jan 21, 2008, at 7:43 AM, Jonathan Rockway wrote:
> Along these lines, how is everyone doing multi-page forms?  I like  
> to do
> GET/POST/redirect, but that needs the session to get the data from  
> page
> 1 to page 2.  Without a session, I use the old "POST returns the form
> with hidden fields that is page 1", but i *hate* that technique.  So I
> use the session.

I'm going through this as well right now, doing a small checkout- 
style multi-step form. The following is my current idea on how to  
deal with this. Its still a rough draft but I think it will work ok.  
Any feedback is appreciated.

Below, when I mention PUT, i'm using PUT-tunneled-over-POST for web  
clients.

Users start by POST'ing to /checkout/start. This will create a cart  
containing the items to include in this checkout. In our case, we  
always include all the items currently pending payment, other sites  
might have a different policy/requirements. The point of this first  
step is to create a cart, with a unique identifier. We associate the  
cart with the logged in user and we include a security hash based on  
the cart id and user id on each form. After all this, we redirect to / 
checkout/cart/UNIQUE_ID/step1.

On each step, the GET will show the appropriate form. The user will  
fill the fields, and PUTs the result to the same address. Information  
received is checked and valid fields are stored in the cart state.  
After that, if all fields are correct, we redirect to the next step.

If they are not correct, we redirect to the same URL. Previous  
values, and error messages or error codes are given back using URL  
parameters. Usually we have very little parameters and they are all  
limited in size, so it fits the 1k max URL size.

Aside: If a field is unusually large, we need some kind of temporary  
storage, and this could break somewhat the Idempotence of each  
request. We could sha1 hash the bad content, store it somewhere keyed  
on this hash and send the hash to the client. This might solve it.  
Fortunately I never needed this.

On each step, the process updates the fields on the cart, and at the  
final step, we change the status of the cart to 'ready_to_process'  
and redirect the user to a success page.

The things I like on this approach:

Every request is idempotent: you can reload to your hearts content  
any page, you can post several times each step to update previous  
entered information, you can go back and forward, everything.

There is no final step of copying the cart usually stored in the  
session to your orders table. The cart is the order, you build the  
order step by step until its ready to be processed by our back-office  
staff.

Old, unfinished orders can be cleaned up after some time, and if they  
are request in the future you can just create a new one and redirect  
to it, or you can give the user a error message and suggest the  
creation of a new one. I keep carts for one year or until the items  
in it expire, but that's my business :). Yours might need different  
timings. You could also erase old carts based on the step they are at.

If you start a new checkout with another one still open, there are  
several options. My personal choice is to merge the old order with  
the new items, but you could also create a new one and suggest  
merging the old one (merging on demand). This part also depends on  
your business needs.

Anyway, this is my currently thinking on this subject. Any feedback  
appreciated.


> (I also use the Flash for "You've added a record
> successfully!" messages.  Totally non-RESTful, but the users seem to
> like it.)

You not redirect with parameters? something like  
po_id=1&p1=Pedro&p2=melo at domain to use message id 1 with two  
parameters, 1=Pedro and 2=melo at domain?

RESTfull, no?

Best regards,
-- 
Pedro Melo
Blog: http://www.simplicidade.org/notes/
XMPP ID: melo at simplicidade.org
Use XMPP!





More information about the Catalyst mailing list