-
-
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?