Looking for ideas on a shopping cart api

96 views
Skip to first unread message

Gary Davis

unread,
Sep 25, 2012, 9:51:08 AM9/25/12
to api-...@googlegroups.com
I would like to expose my shopping cart to other clients to use. I'd like them to be able to create a cart, add items to the cart (delete, update, etc), set the addresses, shipping options and ultimately submit the cart for fulfillment.
 
BTW, I am using ASP.Net MVC4 WebAPI. Cart IDs and Item IDs are GUIDs. SSL and an ApiKey would be required.
 
So I am looking for the best way to design the API Urls. I did not find any "best practice" ideas on the internet but there is a good Apigee PDF on Web Apis that will help. That PDF actually pointed me to this group.
 
So for starting, this is what I am looking at - any critiques are appreciated...
  • GET /api/cart - Request a new empty cart. Return it's guid. Maybe this is not needed.
  • GET /api/cart/[guid] - Request a specific cart along with all items. If it does not exist, return a new empty cart with the guid as its id
  • GET /api/cart/[guid]/[upc] - Request a specific item from the cart based on the upc. If not found, return 404
  • POST /api/cart/[guid] - Update existing cart based on the id.
  • PUT /api/cart/[guid] - Insert a new cart with items (like if 1st GET above is not used).
  • POST /api/cart/[guid]/[upc] - Add/update item to existing cart based on the id/upc.
  • DELETE /api/cart/[guid]/[upc] - Remove existing item from cart
  • DELETE /api/cart/[guid] - Delete (or empty) cart and items
What about things like requesting the list of shipping options based on the cart, its items and shipping destination? What about submitting the cart? Do I use a verb or querystring argument specifying what function is needed?
 
Thanks,
Gary Davis
Webguild
 
For now, I am assuming the order has been paid for so don't have to be concerned about payment methods, credit cards, etc.
 
 

Luke Stokes

unread,
Sep 25, 2012, 11:09:24 AM9/25/12
to api-...@googlegroups.com
Hey Gary, welcome to the group!

You and I are on similar paths, it seems (I develop FoxyCart). I'm relatively new to this stuff and the REST API I've been working on isn't in production yet, but I may be able to offer some ideas.

On Tue, Sep 25, 2012 at 8:51 AM, Gary Davis <gard...@gmail.com> wrote:
I would like to expose my shopping cart to other clients to use. I'd like them to be able to create a cart, add items to the cart (delete, update, etc), set the addresses, shipping options and ultimately submit the cart for fulfillment.
 
BTW, I am using ASP.Net MVC4 WebAPI. Cart IDs and Item IDs are GUIDs. SSL and an ApiKey would be required.
 
So I am looking for the best way to design the API Urls. I did not find any "best practice" ideas on the internet but there is a good Apigee PDF on Web Apis that will help. That PDF actually pointed me to this group.
 
So for starting, this is what I am looking at - any critiques are appreciated...
  • GET /api/cart - Request a new empty cart. Return it's guid. Maybe this is not needed.

This concerns me because you're creating something on the server, correct? A GET shouldn't be doing that. (see http://en.wikipedia.org/wiki/Idempotence and http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html
  • GET /api/cart/[guid] - Request a specific cart along with all items. If it does not exist, return a new empty cart with the guid as its id
The get part is fine, but the creating part has the same concerns as above.

Why not just POST to /api/cart ? Also, do you need the /api/ in the path? Not that it matters, really... one key thing about REST and Hypermedia is that your client shouldn't be coding to the URI anyway. Those should be discovered via the hypmermedia links on the home page.
  • GET /api/cart/[guid]/[upc] - Request a specific item from the cart based on the upc. If not found, return 404
Seems reasonable, I guess. But the guid has more to do with a line item in the cart, right? Are you modeling line items as a resource? 
  • POST /api/cart/[guid] - Update existing cart based on the id.
What do you send as the payload of this POST? 
  • PUT /api/cart/[guid] - Insert a new cart with items (like if 1st GET above is not used).
One thing I learned about PUT is that it has to be the entire document. So I think this is correct. 
  • POST /api/cart/[guid]/[upc] - Add/update item to existing cart based on the id/upc.
  • DELETE /api/cart/[guid]/[upc] - Remove existing item from cart
  • DELETE /api/cart/[guid] - Delete (or empty) cart and items
What about things like requesting the list of shipping options based on the cart, its items and shipping destination?

I would suggest modeling those as resources such as /api/items/[upc] and such. Then your /api/cart/[guid] could have a hypermedia link to /api/cart/[guid]/items (maybe a collection rel value) which returns a collection of items in the cart. Each one of those items has a rel of self to work with that item directly (such as /api/items/[upc])
 
What about submitting the cart? Do I use a verb or querystring argument specifying what function is needed?

The pattern we're thinking of using is POSTing to the cart to transform it into a new resource (a Transaction, in our case). At that point, the cart item is no longer there. We get a 201 and a location header to the new transaction resource. I'm not a fan of verbs in the querystring because I think the HTTP methods give you everything you need when you think in terms or representations and transforming from one state to another.

I hope that's helpful. As we get further along with our API, I'd love for you to take a look. We actually just posted yesterday with some thoughts we're currently working through: http://www.foxycart.com/blog/the-hypermedia-debate#.UGHEUI1lQf7

 
 
Thanks,
Gary Davis
Webguild
 
For now, I am assuming the order has been paid for so don't have to be concerned about payment methods, credit cards, etc.
 
 

--
You received this message because you are subscribed to the Google Groups "API Craft" group.
To unsubscribe from this group, send email to api-craft+...@googlegroups.com.
Visit this group at http://groups.google.com/group/api-craft?hl=en.
 
 



--
Luke Stokes

umbrae

unread,
Sep 25, 2012, 11:45:49 AM9/25/12
to api-...@googlegroups.com
This is good feedback. In addition I'd say that as a general rule the collection resource should be pluralized, like /api/carts. This makes it more clear that this resource houses many carts, not just one. 

Gary Davis

unread,
Sep 25, 2012, 11:57:26 AM9/25/12
to api-...@googlegroups.com
Thanks for the useful info, Luke.
 
The /api on the requests is because the web server hosts other things (mostly .asmx DotNET web services).
 
The GET /api/cart getting a new empty cart does not really create a cart in the database, that's why I think it is not really needed. The caller can create the object and initialize the key (guid) and then use the POST.
 
The GET /api/cart/[guid] returning a cart if not found - it makes sense to instead return a Not Found instead.
 
I am not sure about the hypermedia links you mentioned. I will investigate that (your blog entry from yesterday, for example).
 
The [guid] is basically the cart ID and the [upc] is basically the ID of the items in the cart.
 
Perhaps I should have the items specified in the url as a resource as
 
GET /api/cart/[guid]/items/[upc]
 
Then, to submit a cart as an order for fulfillment and other functions:
 
POST /api/cart/[guid]/order
GET /api/cart/[guid]/shipoptions - Get shipping options/costs based on items/shipping destination
GET /api/cart/[guid]/order - Get order status/confirmation ID
 
Let's say the user selects First Class Shipping from the options. Do I update the cart with the selected option using PATCH (partial update)?
 
PATCH /api/cart/[guid]/shipoptions/[selectedoption] - or use JSON in content
 
Pluralizing to /api/carts is possible. Then GET /api/carts could provide a list of carts based on a filter to get cart(s) for a user, for example.
 
Thanks,
Gary
 
 
 
 

Mike Schinkel

unread,
Sep 25, 2012, 5:33:41 PM9/25/12
to api-...@googlegroups.com
On Sep 25, 2012, at 11:45 AM, umbrae <umb...@gmail.com> wrote:
> ...as a general rule the collection resource should be pluralized, like /api/carts. This makes it more clear that this resource houses many carts, not just one.

+1

-Mike
Reply all
Reply to author
Forward
0 new messages