Skip to content

Instantly share code, notes, and snippets.

@mikekelly
Created March 29, 2011 23:19
Show Gist options
  • Save mikekelly/893552 to your computer and use it in GitHub Desktop.
Save mikekelly/893552 to your computer and use it in GitHub Desktop.
a sketch of application/halo+json & application/halo+xml
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" ]
}
}
]
}
}
}
}
@shishkin
Copy link

Can _controls..template be only URI 'href' and string 'content'? Can I put a custom object in there?

@mikekelly
Copy link
Author

I don't see a reason that could not be allowed.. what are you thinking about using that object for?

@shishkin
Copy link

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.

@mikekelly
Copy link
Author

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

@shishkin
Copy link

Why additional content property? What else can template contain?

I was thinking about something like this: https://gist.github.com/2763291

@mikekelly
Copy link
Author

@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 */
      }
    }
  }

@shishkin
Copy link

And what do you think about the syntax of the template object I've used and the @ descriptors?

@mikekelly
Copy link
Author

they look good to me. do you think this sketch of halo+json would suit your purposes?

@shishkin
Copy link

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.

@nnarhinen
Copy link

@mikekelly is the gist missing templated: true for the search-link by accident or is there a reason behind that?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment