just mentioning from a design perspective: this "form as a separate resource" design is what you almost necessarily end up with when using URI templates. when you fully describe the template, it becomes a template with related descriptions of the additional semantics of the parameters. you can embed this structure everywhere where you're linking to the template-driven resource, or, when it becomes so big that it becomes a bit inconvenient or excessive to do so, you factor it out into its own resource, and then the link links to a URI template, and if you know that one already via caching, you just know what you need to do when you want to follow that link. cheers, dret.
> I think form-as-separate-resource is a fine idea. I hadn't considered
> it, and it took some thought, but I think it's totally fine. Maybe
> there'd be some json-form content-type for that?
> I agree that forms aren't completely evolvable like links are,
> especially in pure m2m scenarios. Here's where you get value:
> 1) Any changes to the form's uri and http method are perfectly safe.
> 2) Human-facing single-page web apps and native apps that take hints
> from the form without understanding the semantics, and render UI
> components that a human would fill in. I believe DOJO and YUI have
> projects doing this from json-schema based forms.
> 3) An in-api standard description that client developers can
> understand at a glance.
> 4) Potential for fuzz-testing crawlers
> Even then, forms-as-separate-resource are a fine idea. I like it.
> G
> On Wed, Oct 17, 2012 at 2:34 PM, Darrel Miller <darrel.mil...@gmail.com> wrote:
>> I honestly don't think embedded forms add as much value as is
>> perceived and I don't think they are the best approach.
>> Let's consider a concrete example,
>> We start with an existing list of foos.
>> GET /foos
>> =>
>> Content-Type: application/hal+xml
>> <resource>
>> <resource rel="http://myapp.com/rels/foo" href="http://myapp.com/foo/23">
>> <description>A small green foo</description>
>> </resource>
>> <resource rel="http://myapp.com/rels/foo" href="http://myapp.com/foo/13">
>> <description>A unlucky foo</description>
>> </resource>
>> <resource rel="http://myapp.com/rels/foo" href="http://myapp.com/foo/42">
>> <description>An enlightended foo</description>
>> </resource>
>> <link rel="http://myapp.com/rels/create-foo" href="http://myapp.com/foos"/>
>> </resource>
>> My client detects that there is a link with the rel
>> "http://myapp.com/rels/create-foo". The client must know either
>> exactly how to activate this link, or it must know that by doing a GET
>> on the link rel URI that it will get more instructions. This is
>> similar to a client retrieving a document and knowing how to process
>> that media type's notion of a form.
>> By splitting the form resource from the actual resource representation
>> itself we get a number of benefits. We don't need to send the form
>> metadata redundantly. It can be cached. We don't need to create a
>> form "mechanism" for hal and collection+json and siren and hyper+json,
>> ad infinitum. The client could negotiate on the types of forms that it
>> understands.
>> We dereference the URI and get back a form description. I just made
>> one up for this scenario, but it would be nice to have a few standard
>> ones. If could be a HTML one, if that is sufficient.
>> GET http://myapp.com/rels/create-foo
>> =>
>> Cache-Control: private
>> Content-Type: application/vnd.acme.formdescriptionlanguage+xml
>> <form-metadata subject="foo" allow="POST" >
>> <property name="description" required="true" maxlength="24" type="string"/>
>> <property name="expires" required="false" type="date"/>
>> <property name="owner" required="false" type="email">
>> <property name="phone" required="true" type="phone-number">
>> <!-- Only required if owner is specified -->
>> </property>
>> </form-metadata>
>> The client can use this metadata to drive it's generic form processing
>> logic. However, it is critical to note that unless this form is going
>> to be generically rendered to a human who will fill in the form, the
>> client absolutely must know about the existence of "description",
>> "expires", etc. Without that knowledge hard-coded into the client, it
>> cannot fill the form.
>> So, once our client knows about the existence of those properties then
>> we are coupled to the content of the form. Which is one of the main
>> points that Mike and I keep going on about. I accept that the form
>> does allow us to dynamically change whether a property is required or
>> not, or in theory the data type of an element, but you cannot rename
>> "expires" to "dateandtimeofdeath" without breaking the client.
>> When you drive a web browser with an HTML form you can change property
>> names, because it is the human can do the translation. If you are
>> doing code download with your own javascript to process the form then
>> sure you can update that "client" along with the form. But those are
>> not the m2m scenarios that we are regularly talking about.
>> Hard coding a client to perform an update purely based on a rel value
>> is not that different to using a form. It's true that you specify
>> default values in a form and round trip those, but you could also put
>> those default values in the query string. It's not like the client is
>> going to know about those values to be able to update them.
>> I fear that by emulating "forms" in hypermedia types that developers
>> are going to get this false sense of security that they will get the
>> same flexibility that they have with embedded HTML forms.
>> To go back to the example, once the client has the form definition,
>> then it should know how to activate that link and how to process the
>> response. In this case the form definition says POST to whatever is
>> in the href and then you are going to get back a representation that
>> can have the properties, as defined by the form definition.
>> POST http://myapp.com/foos
>> =>
>> Content-Type: application/hal+xml
>> <resource>
>> <description>This is the default foo description</description>
>> </resource>
>> The representation that comes back can have default values, just like
>> a HTML form can have default values. The biggest challenge with these
>> "decoupled" forms is that you need a way to correlate the elements in
>> the form with their corresponding piece of data in the returned
>> representation. In this example, I am assuming a simple flat mapping
>> of form "property" to hal "property". However, in a real form
>> media-type this definition may need to be more sophisticated.
>> I guess the main point that I am trying to make with this long winded
>> post is that I believe there is value to separating reads from writes.
>> I don't see a need for each hypermedia format to invent its own
>> mechanism for explaining to the client how to construct a write.
>> Especially considering the write format is likely a different
>> media-type in many cases. I think HTML chose to use embedded forms
>> for a variety of different reasons that are just not as applicable for
>> the scenarios that we are considering today.
>> Darrel
>> --
>> You received this message because you are subscribed to the Google Groups "Hypermedia Web" group.
>> To post to this group, send email to hypermedia-web@googlegroups.com.
>> To unsubscribe from this group, send email to hypermedia-web+unsubscribe@googlegroups.com.
>> For more options, visit this group at http://groups.google.com/group/hypermedia-web?hl=en.
> --
> You received this message because you are subscribed to the Google Groups "Hypermedia Web" group.
> To post to this group, send email to hypermedia-web@googlegroups.com.
> To unsubscribe from this group, send email to hypermedia-web+unsubscribe@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/hypermedia-web?hl=en.