JornWildt / Mason

Documentation and examples for the Mason media type
MIT License
114 stars 6 forks source link

Considering moving all links, templates and actions into one element? #10

Closed JornWildt closed 9 years ago

JornWildt commented 10 years ago

Consider the following scenario:

  1. An API has a link template requiring one single parameter X:
"@link-templates":
{
  "foo:a":
  {
    template: "http://example.com/items/{x}",
    parameters:
    {
      "name": "x",
    }
  }
}
  1. A client looks for "foo:a", finds the link template, fills out the parameters and issues a GET on the resulting URL.
  2. Server developers decides that a POST is needed instead. The parameter is still "x" but now it has to be JSON encoded and POSTed instead.
  3. So the server devs moves "foo:a" to @actions instead:
"@actions":
{
  "type": "json",
  "href": "http://example.com/items",
}
  1. Now the client comes back and looks for "foo:a" in the link template collection. Its not there! So the client fails ...

Now we can take two different approaches: either the client must be prepared to also look into the @actions collection - or we can move all links, link templates and actions into one single @operations collection - with a required "operation" property specifying whether its a link, link template or an action.

In the scenario above it would first be:

"@operations":
{
  "foo:a":
  {
    operation: "link-template",
    template: "http://example.com/items/{x}",
    parameters:
    {
      "name": "x",
    }
  }
}

and then

"@operations":
{
  "foo:a":
  {
    operation: "action",
    type: "json",
    template: "http://example.com/items/",
  }
}

In this case the client always looks for "foo:a" in the @operations collection and then switch "operation" to figure out how to handle the operation.

(Would be nice with a better name than "operation" though)

vtsukur commented 10 years ago

Very good point!

I'd suggest grouping all links under @links to keep standard hypermedia term of the link in place. Then just add an argument called action or operation.

UBER uses action with four posible values:

By having action or operation there will be no need to support method directly.

JornWildt commented 10 years ago

By having action or operation there will be no need to support method directly.

Nah, actions in Mason are different from Uber. A Mason action can for instance be of type "json" (for sending a JSON encoded payload) or "json+files" (for sending multipart content) - both of these can be sent using either POST or PUT, so the method would still be required.

vtsukur commented 10 years ago

I see, you are talking about additional type of the @action which is specific to Mason: any, json, json+files, void. That is true, actions in UBER and Mason are different.

But I meant a bit different thing, let me clarify.

AFAIU you are trying to unify links in some way. You add operation as an attribute of the link. My suggestion is that operation (or action, kind, flavor, etc.) may map to HTTP method automatically if we give such semantics to it. It is great because it also describes the purpose of the operation:

"@links": {
  "foo:a": {
    operation: "read", // this is a default operation, corresponds to LO in H-Factors, maps to HTTP GET.
    href: "http://example.com/items"
  },
  "foo:b": {
    operation: "append", // corresponds to LN in H-Factors, maps to HTTP POST
    type: "json",
    href: "http://example.com/items"
  },
  "foo:c": {
    operation: "read",
    template: "http://example.com/items/{x}",
    parameters:
    {
      "name": "x",
    }
  }
  ...
}

This way linking concept is unified.

Again, this is just the suggestion ;)

JornWildt commented 10 years ago

Well, I don't really agree with UBER's way of mapping some UBER specific "operation" to a HTTP method in Mason. It makes sense for UBER since it is protocol agnostic - but Mason is not trying to be so.

I can imagine scenarios where "read" can be done with GET as well as POST - like for instance POSTing a big query in order to perform some advanced search..

JornWildt commented 10 years ago

But continuing on the unification in Mason. It could perhaps make sense to map "type" to "link/template/action" and then use "format" for "any/json/json+files/void". Have to think more about this :-)

JornWildt commented 9 years ago

The version 2 specification will combine all links, link templates and actions into a single object. Right now the name is "@navigation" but I am looking for something better.