views:

426

answers:

6

I am working on a small client server program to collect orders. I want to do this in a "REST(ful) way".

What I want to do is:

Collect all orderlines (product and quantity) and send the complete order to the server

At the moment I see two options to do this:

  1. Send each orderline to the server: POST qty and product_id

I actually don't want to do this because I want to limit the number of requests to the server so option 2:

  1. Collect all the orderlines and send them to the server at once.

How should I implement option 2? a couple of ideas I have is: Wrap all orderlines in a JSON object and send this to the server or use an array to post the orderlines.

Is it a good idea or good practice to implement option 2, and if so how should I do it.

What is good practice?

+1  A: 

You won't want to send the HTTP headers for 100 orderlines. You neither want to generate any more requests than necessary.

Send the whole order in one JSON object to the server, to: server/order or server/order/new. Return something that points to: server/order/order_id

Also consider using CREATE PUT instead of POST

Cheery
I suppose he ment HTTP POST method. There is no such a thing as CREATE HTTP method.
Milan Novota
Isn't there? Oh wait, there weren't. There were PUT instead.
Cheery
+1  A: 

Your idea seems valid to me. The implementation is a matter of your preference. You can use JSON or just parameters for this ("order_lines[]" array) and do

POST /orders

Since you are going to create more resources at once in a single action (order and its lines) it's vital to validate each and every of them and save them only if all of them pass validation, ie. you should do it in a transaction.

Milan Novota
+1  A: 

Although Bulk operations (batch create) are essential in many systems, were not formally addressed by the RESTful architecture style.

I found that posting a collection as you suggested is fine.But the problem starts when you need to report failures on part of the collection, and the problem is worsen when they failures have different cause or the server doesn't support transactions. So my suggestion to you is that if there is no performance problem, for example when the service provider is on the LAN (not WAN) or the data is relatively small, it's worth to send 100 post requests to the server. Keep it simple, start with separate requests if you have a performance problem try to optimize.

LiorH
+1  A: 

I guess it's better to send separate requests within single connection. Of course, your web-server should support it

zakovyrya
A: 

I believe that Pipelining is the answer you need, which is described in the previous comments "single connection" link.

Eric Pabst
A: 

It depends on the user-experience you need. If you want to validate additions to the order as the user adds items, you'll need to send them separately, after that you either resend the finished collection to commit it, or you sent some kind of commit command.

It depends which of these looks more restful to you:

>GET /order/new
<{status: 0, orderId: 1000}

>PUT /order/1000/addItem
>{itemId: 505, variation: {color: 1, size: 32}, quantity: 1}
<{status: 0, orderId: 1000, itemLine: 0}

>PUT /order/1000/addItem
>{itemId: 501, variation: {color: 2, size: 33}, quantity: 1, option:{gift:true}}
<{status: 0, orderId: 1000, itemLine: 1}

>PUT /order/1000/addItem
>{itemId: 501, variation: {color: 1, size: 34}, quantity: 1}
<{status: 1, statusExplanation: "Backordered", orderId: 1000, itemLine: 2}

>PUT /order/1000/addCustomer
>{customerId: 200}
<{status: 0}

or

>PUT /order/new
>{
> items:[
> {itemId: 505, variation: {color: 1, size: 32}, quantity: 1},
> {itemId: 501, variation: {color: 2, size: 33}, quantity: 1, option:{gift:true}},
> {itemId: 501, variation: {color: 1, size: 34}, quantity: 1}],
> customerId: 200}
<{orderStatus: 0,
< orderId: 1000,
< itemStatus: [0,0,1], itemStatusExplanation:['','','Backordered'],
< itemRows: 3,
< customerStatus: 0}
dlamblin