Action Types Proposal

175 views
Skip to first unread message

Michael Tiller

unread,
Feb 23, 2016, 3:46:02 PM2/23/16
to Siren Hypermedia
  I've been using Siren for a project.  One of the big selling points was the ability to describe actions explicitly in responses.  This allows me to make the client "dumber".  I've been working on a framework for creating hypermedia APIs around this.

  But one thing I find somewhat limiting in Siren is the fact that it doesn't really have a complete way of describing the data that goes into an action.  The spec talks about "application/x-www-form-urlencoded" and HTML5 input types.  Those work fine together, but what about if you POST "application/json"?  What about if you post a file?

  In thinking about it, it seems to me that the current approach of specifying "type" and "fields" independently is problematic.  Your specification of what the action "takes" as input is strongly related to what format that data is in.  So this got me thinking...what if "type" were an *object* where the content types were the keys and a specification of the "fields" (in a content types appropriate form) were the values.  So, for example, if you post with application/x-www-form-urlencoded then you use HTML5 input types (just as you do now) to specify the payload, but if you post application/json, it's a JSON schema and if you post "multipart/..." maybe it's a specification of content types for each part (I don't know, but you get the idea).

  So an action would then look like this:

"actions": [
    {
      "name": "add-item",
      "title": "Add Item",
      "method": "POST",
      "href": "http://api.x.io/orders/42/items",
      "type": {
        "application/x-www-form-urlencoded": [
          { "name": "orderNumber", "type": "hidden", "value": "42" },
          { "name": "productCode", "type": "text" },
          { "name": "quantity", "type": "number" }
        ],
        "application/json": {
           "type": "object",
           "properties": {
              "orderNumber": { "type": "number" },
              "productCode": { "type": "string" },
              "quantity": { "type": "number"},
           }
        }
      }
    }
  ],

The essential point here is that if you really analyze the issue I think this makes much more sense.  The link between "type" and specification of data is just too "strong" to treat them as orthogonal.

I'm curious, what do people think about this?  Could this be a candidate for Siren v.Next?

This works really nicely for what I'm working on because it lines up very well with the server side.  When a request is made with a body, I need to process it on the server side.  It has the big advantage that a) it allows us to express support for multiple formats and b) it mirrors what kind of validation that is being done on the server side already...so all the server needs to do is export the validation details in the Siren response (rather than trying to "bend" all possible validation formats to HTML5 inputs).

An open issue would be...should the Siren spec really say "for application/json, you must use JSON Schema to express validation"?  Well, for starters Siren *already* specifies validation information (but in a way that is far more constraining...since there is only one option).  Furthermore, I think you can come up something reasonable at least as a default validation format for many content types.  But perhaps this could also include a way to express alternatives, e.g. "application/json;validateWith=<description>": { ... }.

Comments?

--
Mike

Michael Tiller

unread,
Feb 23, 2016, 3:56:12 PM2/23/16
to Siren Hypermedia
Going back and reviewing the thread from last November, another alternative could be to combine this with something that Kevin mentioned about out-of-band stuff:

"actions": [
    {
      "name": "add-item",
      "title": "Add Item",
      "method": "POST",
      "href": "http://api.x.io/orders/42/items",
      "type": {
        "application/x-www-form-urlencoded": "/link/to/html5ish/field/data",
        "application/json": "/link/to/json-schema"
      }
    }
  ],

This has two advantages.  First, it keeps the "action" specification smaller by not inlining the data.  Second, you could use the content type of the response from "/link/to/json-schema" (e.g., application/schema+json) to indicate what the validation data format really was.

Sorry, I should have reviewed that past thread before my last post.  But my point remains...I think it would be good to support multiple formats and I think it should be possible to express the validation specification on a per content type basis.

--
Mike

Alex Soto

unread,
Feb 23, 2016, 11:24:55 PM2/23/16
to siren-hy...@googlegroups.com
my preference, is that Siren stay as simple as possible with html5/form input types instead of trying to define all possible input formats.   Then extensions to the spec can each define specifics (json inputs with json-schema, etc)

I have limited siren implementation experience (one api), but in my experience, multiple input formats is not something that's even been mentioned as a need.

--
You received this message because you are subscribed to the Google Groups "Siren Hypermedia" group.
To unsubscribe from this group and stop receiving emails from it, send an email to siren-hypermed...@googlegroups.com.
To post to this group, send email to siren-hy...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/siren-hypermedia/cb10377b-974a-4ba7-9096-385f99b54b8e%40googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

Mathias Reichardt

unread,
Feb 25, 2017, 6:46:10 AM2/25/17
to Siren Hypermedia

Old thread but anyway:

I am currently using this approach in my project:


"actions": [
   
{
     
"name": "CustomerMove",
     
"title": "A Customer moved to a new location.",
     
"method": "POST",
     
"href": "http://myapi/Customers/1/Move",
     
"type": "application/json",
     
"fields": [
       
{
         
"name": "NewAddress",
         
"type": "application/json",
         
"class": ["http://myapi/Customers/NewAddressType"]
       
}
     
]
   
},
   
...
 
],


I intend to tell the client that I expect a JSON object of type NewAddressType. The class link provides a JSON schema generated on the server. So a client can resolve it at run time and generate a schema conform UI or validate against it.


This can also be used to generate or validate objects at compile time by talking to implemented server or a mock server (e.g.blueprint + drakov).

Reply all
Reply to author
Forward
0 new messages