-
-
Save mikekelly/893552 to your computer and use it in GitHub Desktop.
| I've added a control element with these properties/attributes: | |
| method ; method to use for generated request e.g. POST/PUT/DELETE | |
| content-type ; (optional) content-type of the request body generated by the template (defaults to application/hal+xml) | |
| schema ; contains schema for data submitted to template | |
| template ; (optional) A string or object representing the template or form for the request. | |
| template-href ; (optional) Contains a URI which links to a resource where the template or form can be fetched. | |
| template-type ; (optional) URI used to identify the template format in use (defaults to mustache). |
| { | |
| "_links": { | |
| "self": { "href": "/" }, | |
| "basic": { "href": "/bleh" }, | |
| "search": { "href": "/search_for;{searchTerm}" } | |
| }, | |
| "_controls": { | |
| "widgetate": { | |
| "href": "/widget/{newID}", | |
| "method": "PUT", | |
| "content-type": "application/xml", | |
| "schema": null, | |
| "template": "<widget>\\n <name>{{name}}</name>\\n\\n <blobs>\\n {{#blobs}}\\n <blob>\\n {{#first}}\\n <first>true</first>\\n {{/first}}\\n <contents>{{contents}}</contents>\\n </blob>\\n {{/blobs}}\\n </blobs>\\n\\n {{#is_empty}}\\n <note>This is an empty widget</note>\\n {{/is_empty}}\\n</widget>\\n" | |
| } | |
| } | |
| } |
| <resource href="/" xmlns:ex="http://example.org/rels/"> | |
| <link rel="basic" href="/bleh" /> | |
| <link rel="search" href="/search_for;{searchTerm}" /> | |
| <control rel="widgetate" href="/widget/{newID}" method="PUT" content-type="application/xml" > | |
| <widget> | |
| <name>{{name}}</name> | |
| <blobs> | |
| {{#blobs}} | |
| <blob> | |
| {{#first}} | |
| <first>true</first> | |
| {{/first}} | |
| <contents>{{contents}}</contents> | |
| </blob> | |
| {{/blobs}} | |
| </blobs> | |
| {{#is_empty}} | |
| <note>This is an empty widget</note> | |
| {{/is_empty}} | |
| </widget> | |
| </control> | |
| </resource> |
| { | |
| "_links": { | |
| "self": { "href": "/" }, | |
| "basic": { "href": "/bleh" }, | |
| "search": { "href": "/search_for;{searchTerm}" } | |
| }, | |
| "_controls": { | |
| "widgetate": { | |
| "href": "/widget/{newID}", | |
| "method": "PUT", | |
| "content-type": "application/xml", | |
| "template-href": "/widget.template" | |
| } | |
| } | |
| } |
| <resource href="/" xmlns:ex="http://example.org/rels/"> | |
| <link rel="basic" href="/bleh" /> | |
| <link rel="search" href="/search_for;{searchTerm}" /> | |
| <control rel="widgetate" | |
| href="/widget/{newID}" | |
| method="PUT" | |
| template="/widget.template" | |
| content-type="application/xml" /> | |
| </resource> |
| <widget> | |
| <name>{{name}}</name> | |
| <blobs> | |
| {{#blobs}} | |
| <blob> | |
| {{#first}} | |
| <first>true</first> | |
| {{/first}} | |
| <contents>{{contents}}</contents> | |
| </blob> | |
| {{/blobs}} | |
| </blobs> | |
| {{#is_empty}} | |
| <note>This is an empty widget</note> | |
| {{/is_empty}} | |
| </widget> |
| { | |
| "_links": { | |
| "self": { "href": "/" }, | |
| "basic": { "href": "/bleh" }, | |
| "search": { "href": "/search_for;{searchTerm}" } | |
| }, | |
| "_controls": { | |
| "order": { | |
| "href": "http://...", | |
| "method": "POST", | |
| "template-type": "http://shishkin.org/json-templates", | |
| "template": { | |
| "location": "", | |
| "@location": { | |
| "prompt": "Enter your postal code" | |
| }, | |
| "pickupTime": "", | |
| "@pickupTime": { | |
| "prompt": "When do you want to pickup your order?", | |
| "type": "dateTime" | |
| }, | |
| "items": [ | |
| { | |
| "name": "espresso", | |
| "@name": { "options": [ "espresso", "cappuchino", "latte" ] }, | |
| "size": "normal", | |
| "@size": { "options": [ "normal", "grande", "venti" ] }, | |
| "additions": [], | |
| "@additions": { | |
| "multiple": true, | |
| "item": "string", | |
| "options": [ "shot", "caramel", "vanilla", "decaf" ] | |
| } | |
| } | |
| ] | |
| } | |
| } | |
| } | |
| } |
I don't see a reason that could not be allowed.. what are you thinking about using that object for?
In case of a POST or PUT method I want to provide the client with a template object it can directly put into the request, optionally with modifications it can understand.
@shishkin ok, what would that JSON template object be?
Seems like the best place for this template object would be under template.content, so a library can determine that the template is inline by checking to see if template.content is defined or not. What do you think ?
Why additional content property? What else can template contain?
I was thinking about something like this: https://gist.github.com/2763291
@shishkin my thinking was that it would conflict with external templates which also use an object for template.content.href.
I think you are right though - perhaps the solution is to do away with template.content altogether, so the template property can either be a string (e.g. a mustache template) or an object (as in your example). External templates can be linked to via a separate property template-href. This solves all issues.
According to this design then, all you need to do is choose a URI which identifies your template format, e.g. http://shishkin.org/json-templates
"_controls": {
"an-example": {
"href": "/widget/{newID}",
"method": "PUT",
"content-type": "application/json",
"template-type": "http://shishkin.org/json-templates",
"template": {
/* a template json object in your format goes here */
}
}
}
And what do you think about the syntax of the template object I've used and the @ descriptors?
they look good to me. do you think this sketch of halo+json would suit your purposes?
Yes, that would give me the HTML forms-like functionality that I missed in HAL. Would love to see it make into HAL.
I'll soon come up with a stawman version of the lightweight descriptor-based templating syntax for a community review.
@mikekelly is the gist missing templated: true for the search-link by accident or is there a reason behind that?
Can _controls..template be only URI 'href' and string 'content'? Can I put a custom object in there?