views:

162

answers:

4

I am still in the process of getting comfortable with doing things the REST way.

In my situation, client software will be interacting with a RESTful service. Rarely, the client will upload its entire database of entities (each entity serializes into a roughly 5kb chunk of xml).

Perhaps I'm wrong, but the proper RESTful strategy seems to be to cycle through each entity and individually POST each one. However, there may plausibly be tens of thousands of these entities, and somehow so many rapid-fire POSTs doesn't seem kosher.

In this situation, it feels like packaging all the entities into one big xml representation would violate the RESTful way of doing things, but it would also avoid the need for thousands of POSTs.

Is there some standard-practice for accomplishing this? Thanks in advance!

+3  A: 

I don't see why a "Packet of entities" cannot be considered a resource. Transactional writes certainly can consider database transaction to be a resource. I admit I haven't read Fielding's dissertation, but I don't see how wrapping several resources into a single representation would invalidate REST.

Database transactions do something like this. They will wrap smaller resources inside a transaction resource. It's true that usually they do this so that you can post those smaller resources, that can still be large, separately. But since the transaction itself is considered a resource, I don't believe that coming up with a representation for it that you could post as one POST request would make this design any less RESTful.

It's also used to the other direction. When the client GETs search results from the server, the server might wrap these inside a results resource so that the client can just get this one resource instead of several separate ones.

So I'd say that wrapping these small 5kb resources inside a larger collection resource can be considered RESTful and is probably the way you should go for.

Mikko Rantanen
I was thinking along these lines, so that I would allow clients to POST the update packet to a resource found at www.myservice.com/updateset/Then this resource would only support POST and not get/delete/put, which seems to me to at least slightly break the resource abstraction. For now, though, I can't think of any better way.
tempy
+1  A: 

As long as the big wrapper has a valid media-type then it is fine to treat it as a single resource. Figuring out what that media-type is going to be is the tricky part.

Darrel Miller
Thanks for your continually accurate advice on REST. Everyone else focuses on URIs, but you remind us that media-types are a far more important issue. I can't believe how overlooked this is.
Wahnfrieden
It is good to hear another voice on Stack Overflow that has not been mislead by the vendors' push to dilute the REST message. The number of us is starting to grow but the number of "How do I create a RESTful url with technology X?" questions do not seem to subside!
Darrel Miller
A: 

There are at least two problems here which prevent you from being RESTful.

  1. Each resource needs to be identified by a URI. Acting on the resource means that you must call the URI using an HTTP call. Consequently, you cannot call multiple actions in multiple resources in just one HTTP call.

  2. The resources are identified by nouns and represent entities. This implies that to insert an Employee and a Car you need to call two different resources for each of the respective entities.

So in summation you cannot take a purely RESTful approach here. However, REST is designed to help by way of conventions, not constrict you. The best solution here is for you to create a custom action which does what you need.

Alternately, you can create a generic wrapper entity with INSERT, UPDATE and other actions which take in blobs of disparate data as XML. However, this will undermine your other end points because now it becomes possible to insert a Car record through the generic wrapper and through the /Car/ URI.

Without knowing much about your actual requirements, I would suggest you don't expose this functionality via REST specifically. Behind the scenes you could still call your INSERT action methods within the various Controllers once you break up the incoming collection if disparate objects.

aleemb
Just because you have a resource foo does not mean you cannot have another resource "list of foo".There is no requirement for a resource to correspond to an "entity", assuming your talking about the database kind of entity.
Darrel Miller
I want to expose this functionality via REST because my service will be a RESTful service on google app engine. Adding SOAP-style RPC calls into the mix (or something similar), on this platform especially, would be both ugly and difficult.I think I will create an abstracted "updateset" resource that will only support POST, as I wrote to the last question. You are right though, that this will allow entities to be updated both through this resource and through the specific URIs of the individual resource. Is this so bad?
tempy
Darell, I didn't say you can't do that. It is redundant from a design perspective but you can certainly have two resources for "car" and "cars" but that design gets confusing very fast.
aleemb
Darrel, in this case the proper name of the resource would be "list of foos synchronized from a client's cache to the service." This sort of resource is a lot more logically confusing than simply "list of foo".
tempy
@tempy, to answer your question, that's a perfectly reasonable approach.
aleemb
@aleemb Atom Feed, Atom Entry. Feed is basically a collection of entries. Doesn't seem too confusing to me.
Darrel Miller
There is nothing impossible to design in a RESTful manner if you want to post to a list a list of entities in one go, it depends on how you design you media type. Thats what POST is about, "accept the following resource representation as a subresource". Nothing to do with inserts etc.
serialseb
A: 

Nothing prevents you from creating more resources upon addition, aka post a resource that is a list of X to a resource that's a list of X using a POST.

You'd then send back a 201 created with the list of URIS of all resources created. Again, it's all perfectly allowable.

What you loose is the visibility to the intermediaries upon PUT, which prevent them from caching or modifying the specific resource at the specific URI. Although a smart intermediary would process the 201 for caching purposes.

And having one doesn't prevent you from having each created resource have its own URI post-creation (after the POST) and enable PUT / DELETE on those resources. Or a combination.

serialseb