Unifying links and actions?

53 views
Skip to first unread message

Jørn Wildt

unread,
Jun 23, 2014, 1:43:45 AM6/23/14
to mason-me...@googlegroups.com
Hi,

I would like to ask the few of you on the Mason mailing list how you would react to this proposal: https://github.com/JornWildt/Mason/issues/11

I am proposing to combine links, link-templates and actions into one single @links construct.

Kind regards, Jørn

nick.p...@gmail.com

unread,
Feb 13, 2015, 10:52:16 AM2/13/15
to mason-me...@googlegroups.com
I haven't read the proposal yet, hope to soon, but I had been wondering what the difference, and why, between links and actions.  For instance, how does a outbound navigational link (LO) differ from a query template (LT) or a update template (LI or LN)?  I assume an outbound navigational link is always assumed to be safe, but other than that is there some other differences?  I assume LO involves a state transition.  I assume LI and LN also involve a state transition.  And then there is LE, which I'm not sure how useful it is in an API hypermedia type.  Does that involve a state transition?

It would seem that if a link had a href, link relation, optional method, optional accept types, optional content type, optional template it would cover both links and actions.  Am I forgetting something?  Not sure if you need to support LE.

Thanks,
Nick

Jørn Wildt

unread,
Feb 15, 2015, 2:57:15 AM2/15/15
to mason-me...@googlegroups.com
> It would seem that if a link had a href, link relation, optional method, optional accept types, optional content type, optional template it would cover both links and actions.  Am I forgetting something?

Yes, that is more or less what I am aiming for ... here is a short abstract of the current state:

- Links, links templates and actions are all represented in the same property named @controls (but this could change, @links is also a possibility)

- Links and actions are distinguished by an optional "type" property. The default value indicates a request with no payload (mostly a GET but DELETE is also possible).

- All controls may have a templated "href".

- All controls can have a "method" assigned. The default is GET for links and POST for others.

- All controls can have documentation properties "title" and "description".

Examples:

A simple link:

@controls
{
  self:
  {
    href: "http://..."
  }
}

A documented link:

@controls
{
  up:
  {
    href: "http://...",
    title: "Links to xxx",
    description: "... in depth text ..."
  }
}

A templated link:

@controls
{
  query:
  {
    isHrefTemplate: true,
    title: "Search for issue"
  }
}

- Right now I am debating whether to continue using a special "hrefTemplateParameters" list that documents the available URL template parameters - or simply share the parameters with the (optional) payload and let it all be described by JSON schema.

So, for instance, here is a templated link with schema describing the template parameters:

@controls
{
  query:
  {
    href: "http://example.com/issues{?query}",
    isHrefTemplate: true,
    schemaUrl: "http://...",
    title: "Search for issue"
  }
}

A basic JSON action (default method is POST):

@controls
{
  create:
  {
    href: "http://example.com/...",
    type: "json",
    schemaUrl: "http://...",
    title: "Create new issue"
  }
}

A JSON action with a templated request body:

@controls:
{
  create:
  {
    href: "http://...",
    type: "json",
    schemaUrl: "http://...",
    template:
    {
      title: "Enter title",
      severity: 3,
      trackingId: "87bd83hja",
      securityToken: "7nbdi-2367eg",
      last-updated: "2015-01-01T10:32:10"
    }   
  }
}

- In the above example the client is supposed to take the "template" object and merge its request values into it, such that for instance "title" and "severity" is replaced with user input, but "trackingId", "securityToken" and "last-updated" are kept unmodified (for business tracking, security and avoiding lost updates).

The most complex example combines a templated URL and a request body. The description below is equivalent to the previous one:

@controls:
{
  create:
  {
    href: "http://...?trackingId=87bd83hja&title={title}",
    isHrefTemplate: true,
    type: "json",
    schemaUrl: "http://...",
    template:
    {
      title: "Enter title",
      severity: 3,
      securityToken: "7nbdi-2367eg",
      last-updated: "2015-01-01T10:32:10"
    }   
  }
}

The client is supposed to react as follows:

- If no template object exists then use an empty JSON object as default value.

- Take the template object and merge it into the UI (not required, but recommended).

- Let the user change values.

- Merge the user input into the template object.

- Evaluate the URL template and replace parameters with values from the template object.

- Initiate the HTTP request with the assigned method, at the calculated URL, with the template object serialized as JSON in the body.

Then we have some special cases like having a link(?) with a DELETE method:

@controls
{
  remove:
  {
    href: "http://...",
    method: "DELETE"
  }
}

Another funny ability (that Darell Miller pointed out in another discussion group) is to be able to POST a raw image to a URL where the image title and similar is encoded in the URL:

@controls:
{
  addImage:
  {
    method: "POST",
    type: "raw",
    accept: ["image/jpeg", "image/png"],
    schemaUrl: "http://..."
  }
}

/Jørn

- Merge the








--
You received this message because you are subscribed to the Google Groups "Mason media type" group.
To unsubscribe from this group and stop receiving emails from it, send an email to mason-media-ty...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

nick.p...@gmail.com

unread,
Feb 15, 2015, 5:32:39 PM2/15/15
to mason-me...@googlegroups.com
And type is for content type of a payload?

If so, is it true that all links (navigational) won't have a payload?

Also, maybe some better naming is in order.  When you say links I assume you mean a navigational link, and I'm not even sure if that's a good name for it.  Maybe a relational link.  Though that might not be too good either as we have link "relations" for actions.  Maybe navigational link is better.  At any rate, what differentiates a navigational link from an action.  I'm guessing when following a navigational link you'll always use a safe transport method.  And when following a navigational link you're most likely following a relationship, even if the relationship happens to be "self".  Whereas when following an action link you're not following a relationship but instead performing some sort of action "on a resource" or "related to a resource".

Thanks,
Nick

Jørn Wildt

unread,
Feb 16, 2015, 3:03:24 AM2/16/15
to mason-me...@googlegroups.com
Yes, naming is a a hard problem (http://martinfowler.com/bliki/TwoHardThings.html) ... and I do agree that there is a problem which needs fixing.

And, yes, links do not have a payload ... but actions doesn't have to have a payload either (consider a DELETE action for instance - or an empty POST). So we cannot use that to distinguish.

Links is for navigation and relationship between two resources. Links uses GET and is thus safe. Everything else is an action and depends on an unsafe HTTP method (ignoring OPTIONS here).

"type" is a bit special:

- If "type" is "json" then the content type must be JSON (application/json), but the client must also acknowledge the "schemaUrl" and "template" properties that defines the shape and default values for the payload.

- "type" can also be "json+files" which means the client must use multi-part encoding to combine both uploaded files and a JSON payload.

- Then we have "type=any" (or "raw", haven't decided yet) which means the server and client has to agree on what it means somehow else (through documentation or other methods) - but the server may specify the request content type using "accept". The type "any|raw" is a catch-all for all the scenarios that cannot be handled through simple JSON or multi-part-with-json encoding.

- That leaves us with the last possibility where we have no payload. This is most often a link, but it can also be a DELETE action. So the "type" could be "void" (indicating no payload) or "link" (as it would most often be a link) ... other ideas are welcome.

In addition to that, it is always possible to make the "href" templated, such that a link (with no payload) would have to be aware of certain parameters to fill out the template.

/Jørn

nick.p...@gmail.com

unread,
Feb 16, 2015, 12:45:29 PM2/16/15
to mason-me...@googlegroups.com
I wasn't aware that links, e.g. navigational links, don't have a payload.  Is that true in all cases or are you enforcing it to be true for your design?

I assume a HTTP GET can have a payload, or is that not the case?

Thanks,
Nick

Jørn Wildt

unread,
Feb 16, 2015, 1:35:01 PM2/16/15
to mason-me...@googlegroups.com
As per http://tools.ietf.org/html/rfc7231#section-4.3.1

>>> A payload within a GET request message has no defined semantics; sending a payload body on a GET request might cause some existing implementations to reject the request.

So its not explicitly forbidden to have a payload (request body) with GET, but very unusual and really not recomended.

/Jørn

nick.p...@gmail.com

unread,
Feb 19, 2015, 9:15:49 AM2/19/15
to mason-me...@googlegroups.com
As I'm working on some examples of an API, just crufting up by hand, I happen to be at a search link where my current thinking is that maybe the URL doesn't include the search terms but instead the search terms are in the payload.  The request will be a GET request as it's safe operation.  This doesn't seem that atypical.

Thanks,
Nick

Jørn Wildt

unread,
Feb 19, 2015, 9:21:59 AM2/19/15
to mason-me...@googlegroups.com
This is a classic use case for a link template :-) It is both normal and expected to include query terms in the URL. Like for instance:

  /items{?category,color}

which could be expanded into

  /items?category=animals&color=red

or with textual searches like google:

  /answers?q=are+horses+green

You might want to take a look at the sections "Filtering" and "Handling large input filters" at http://soabits.blogspot.dk/2013/10/url-structures-and-hyper-media-for-web.html

/Jørn

nick.p...@gmail.com

unread,
Feb 19, 2015, 11:39:43 AM2/19/15
to mason-me...@googlegroups.com
Thanks.  I did look over the link you sent.

While I'm aware that many people use the URL for search terms it could be the case that there is a significant amount of people who don't.  I'm just suggesting that there could be a fair amount of get operations which include a request payload.

Nick
Reply all
Reply to author
Forward
0 new messages