Hi Richard,

Option 3 seems the best to me. Note that when you do a PUT you shouldn't
send a partial representation as the entity sent is expected to fully
replace the existing representation.

Another option you could consider is to give an URI to each modifiable field
and update them individually.

Best regards,
Jérôme Louvel
--
Restlet ~ Founder and Lead developer ~ http://www.restlet.org
Noelios Technologies ~ Co-founder ~ http://www.noelios.com
 

-----Message d'origine-----
De : Richard Hoberman [mailto:[EMAIL PROTECTED] 
Envoyé : vendredi 17 octobre 2008 09:19
À : [email protected]
Objet : Best practices for read-only fields?

Hi

The only advice Richardson seems to offer on incoming representations is
that "a client should be able to fetch a representation, modify it, and
PUT it back where it found it." (RESTful Web Services, 2007, p. 235). 
That is surely right, but how best to handle read-only fields?

For example, consider using GET/PUT to change the nickname on the
following Account object:

Account
   username (read-only)
   registration-date (read-only)
   nickname
   ... many other properties

Option 1.  Only accept representations that don't contain the read-only
fields.  That goes against Richardson's advice, requiring the client to
return a subset of the data.  That is unacceptable.  The client-code
would break if new fields where added to the object and the client-code
would be truly ungainly.  Alternatively, we could allow the client to
PUT a partial representation containing only the fields to be modified,
but that would become tricky when nested structures are involved.

Option 2.  Accept the full representation, but only process writeable
fields.  This is not ideal because it would seem that an attempt to
modify a read-only field had succeeded (silent failure).

Option 3.  Accept the full representation, but reply with a 400
"BAD_REQUEST" if read-only data has been changed.  This seems correct
from a behavioural point of view, although it puts additional burden on
the implementation, which has to check every field to see whether it has
changed - a nuisance, especially where the representation contains
useful reference data.  For example, the outgoing representation of an
itinerary includes the details of the associated agent:

<itinerary>
    <agent>
        <name>...
        <contactDetails>
           ...etc.
    </agent>
    <startDate>1-dec-2009</startDate>
</itinerary>

The user does GET-modify-PUT to change the start-date.  The server has
to check that they haven't attempted to modify the agent's details (just
to avoid the silent failure described at option 2).  This could be
handled as follows:

1.  Annotate read-only fields @ReadOnly
2.  Inside the acceptRepresentation, GET a fresh copy of the resource
3.  Check that copy against the incoming representation by visiting the
full object graph using reflection and comparing the fields annotated as
read-only
4.  Return 400 ("BAD REQUEST") if one or more read-only fields have changed

The visitor could check version numbers at the same time for optimistic
concurrency.

There would be a trade-off of performance for ease of code creation and
maintenance but I think that would be acceptable for the service I am
working on.

I'm now considering option 3.  Anyone have a better way or useful advice?

Best regards

Richard Hoberman

Reply via email to