Well, in a REST interface, following HTTP where ever possible, I would return a 201 and an URI in the Location header field to the newly created Resource. Here is what Status Code Definitions says:
10.2.2 201 Created
The request has been fulfilled and resulted in a new resource being
created. The newly created resource can be referenced by the URI(s)
returned in the entity of the response, with the most specific URI for
the resource given by a Location header field. The response SHOULD
include an entity containing a list of resource characteristics and
location(s) from which the user or user agent can choose the one most
appropriate. The entity format is specified by the media type given in
the Content-Type header field. The origin server MUST create the
resource before returning the 201 status code. If the action cannot be
carried out immediately, the server SHOULD respond with 202 (Accepted)
response instead.
If something went wrong, I would argue you shouldn't return -1
as others have said, but simply a Client or Server Error Code (4xx or 5xx). For example, if a user is not allowed to create some new resource, you would simply return a "401 Unauthorized", nothing more and nothing less.
I think objects are only built correctly around coherent behaviors and not around data. I will provoke and say that data is almost irrelevant in the object oriented world. In fact, it's possible and sometime common to have objects that never return data, for example "log sinks", or objects that never return the data they are passed, for example if they calculate statistical properties.
Let us not confuse the PODS, (which are little more than structures), and the real objects that have behaviors (like the Contacts
class in your example)1.
PODS are basically a convenience used to talk to repositories and business objects. They allow the code to be type safe. No more, no less. Business objects, on the other hand, provide concrete behaviors, like validating your data, or storing it, or using it to perform a calculation.
So, behaviors are what we use to measure "cohesion"2, and it's easy enough to see that in your object example there is some cohesion, even though you only show methods to manipulate top level contacts and no methods to manipulate addresses.
Regarding REST, you can see REST services as data repositories. The big difference with object oriented design is that there is (almost) only one design choice: you have four basic methods (more if you count HEAD
, for example) and of course you have a lot of leeway with the URIs so you can do nifty stuff like pass many ids and get a larger structure back. Do not confuse the data they pass with the operations they perform. Cohesion and coupling are about code and not data.
Clearly, REST services have high cohesion (every way to interact with a resource is in the same place) and low coupling (every resource repository does not require knowledge of the others).
The basic fact remains, though, REST is essentially a single repository pattern for your data. This has consequences, because it's a paradigm built around easy accessibility over a slow medium, where there is a high cost for "chattiness": clients typically want to perform as few operations as possible, but at the same time only receive the data they need. This determines how deep an data tree you are going to send back.
In (correct) object oriented design, any non-trivial application will do much more complex operations, for example through composition. You could have methods for doing more specialized operations with the data -- which must be so, because while REST is an API protocol, OOD is used to build entire user facing applications! This is why measuring cohesion and coupling is fundamental in OOD, but almost insignificant in REST.
It should be obvious by now that analyzing data design with OO concepts is not a reliable way to measure it: it's like comparing apples and oranges!
In fact, it turns out that the benefits of being RESTful are (mostly) the ones outlined above: it's a good pattern for simple APIs over a slow medium. It is very cacheable, and shardable. It has fine grained control over chattiness, etc.
I hope this answers your (quite multifaceted) question :-)
1 This problem is part of a larger set of problems known as Object-Relational impedance mismatch. Proponents of ORMs are generally in the camp that explores the similarities between data analysis and behavior analysis, but ORMs have fallen under criticism of late because they seem not to really resolve the impedance mismatch and are considered leaky abstractions.
2 http://en.wikipedia.org/wiki/Cohesion_(computer_science)
Best Answer
If-Modified-Since
works well for single resources where it is quick and easy to determine if the resource has been modified. For example, HTTP servers have this functionality baked in for static files since it can use the file's timestamp. The general concept is that processing the resource is more expensive than determining it's modification date. I would consider it for single resources, but not for collections.There are several caching schemes to choose from, and you should only use the most appropriate one to solve the need. In some cases, caching is detrimental. Examples:
I've been bitten by a number of proxy-induced caching bugs, particularly old and not well maintained proxy servers in customer networks. Test with multiple users to make sure that your caching efforts don't actually make things worse.