I think I have a basic understanding of REST, but something I'm stuck on is how to request an HTML form to edit a resource.
To my understanding, if the resource is
user/12
And you do a GET on that with content-type "text/html" then you would get some html back that would display the details of that user.
What I don't understand is how to get back html that will display a form that allows you to edit the details of a user (and ultimately send a PUT back to update the user.)
I've seen:
user/12/edit
user/12;edit
Which don't feel super RESTful to me. Personally, knowing nothing else (including whether or not it is valid) I'd consider passing some kind of edit=true parameter on the "Accept:" line of the HTTP header.
Is there a definitive way of doing it?
Edit: I should have explained that I'm implementing the service and wanted to know the proper way of doing it if such existed.
Returning an HTML form as a resource representation tightly couples your presentation and data. It would give you more control if you simply return the basic resource representation (which could be HTML, but I wouldn't expect it to have form elements), and then rely on my client to mark up the data in a way that's editable in HTML.
Additionally, if you were to return an HTML form with the resource marked up in it, how would the form data be sent back to the server? Browsers typically only support POST and GET for form actions - but doing a POST to a resource that already exists isn't RESTful; you would want to be doing a PUT instead. Until browsers support all (or at least more) of the HTTP methods, using RESTful APIs with browser forms directly will be fundamentally broken (at least within the bounds of REST constraints).
Edit:
To answer your question of how you would actually have the client inform the server about how it wants the resource back, you would use content negotiation. Based on the request headers the server returns the resource in an appropriate format. It might use the user agent from the header, or the client might specify a specific Accept
header that the server can obey. It's up to you and your server application to process the header(s) and return the appropriate HTML representation, if available.
Edit2:
Redacted my statement about returning a form not being RESTful, see comments below.
There are no special methods or headers for this sort of thing (responding with the HTML of an editable form for a given resource). And using querystring parameters would only make this worse.
Instead, one might conceptually treat the editable form as resource in its own right, and assign it the path /user/12/edit
. The "postback" would of course be PUT /user/12
(or, in Rails, POST /user/12
and prepend _method=PUT&
to the POST
ed entity).
When one does GET /user/12
, one is asking for a representation of the user. When one does GET /user/12/edit
, one is asking for a representation of a form for the user, rather than a representation of the user directly.
Is this an accurate extension of REST? Is this pure REST? Debatable. But, what else are you going to do?
REST is a concept, not an implementation. Meaning, while your description of a RESTful URL with a Content-Type of text/html returning html is certainly valid, it does not guarantee the return payload. It's up the implementor of the REST service to return the data in its form.
Work backwards from the REST entry you're requesting and look at the return payload. That will tell you everything you need to know about your usage of that URL, and how much work you'll need to do on your consuming side of the equation.
Just for what it's worth - AFAIK, user/12;edit was only used in Rails, and only for a month or two. It was dropped fairly quickly.