kevinswiber/siren

Having a custom field type in action of an entity

Opened this issue · 6 comments

Hello,

We are using siren specification in designing our REST API in one of our project. For some of our entity's actions, we require some complex kind of payload which is not covered by input types specified by http://www.w3.org/TR/html5/single-page.html#the-input-element
And according to siren spec, it says that you may use input types specified by HTML5 for field type. So, i just want to confirm that whether is it a good idea to user some custom field type and provide a link to its description in links field of an entity.

Could you post an example?

Sure, here it is.
Here, i representing the LED ring (component) of a wall plug as a siren entity.

{
    "class": [
        "component"
    ],
    "properties": {
        "id": "a38267e1-e66a-456e-82e2-93a069fdcb70",
        "name": "LED ring of a wall plug",
        "capabilities": [
            "colorable"
        ],
        "color": {
            "hue": 123,
            "saturation": 34,
            "brightness": 98
        }
    },
    "actions": [
        {
            "name": "get-color",
            "href": "http://example.com/components/a38267e1-e66a-456e-82e2-93a069fdcb70/actions/color",
            "method": "GET"
        },
        {
            "name": "set-color",
            "href": "http://example.com/components/a38267e1-e66a-456e-82e2-93a069fdcb70/actions/color",
            "method": "PUT",
            "type": "application/json",
            "fields": [
                {
                    "name": "color",
                    "type": "hsbColor"
                }
            ]
        }
    ],
    "links": [
        {
            "rel": [
                "self"
            ],
            "href": "http://example.com/components/a38267e1-e66a-456e-82e2-93a069fdcb70"
        },
        {
            "rel": [
                "capability"
            ],
            "href": "http://rels.example.com/rels/capabilities/colorable"
        },
        {
            "rel": [
                "valueType"
            ],
            "href": "http://rels.example.com/rels/valueTypes/hsbColor"
        }
    ]
}

Guys, any update on this question.

It depends on whether you want to be a purist or not. A generic siren client won't know what to do with that, but if you are the only consumer (client) implementation, you have the ability to do anything you want.

In my opinion, an action shouldn't have too many parameters. Then it's easy to map to HTML input types with a text field as the fallback and just parse the text on the server to whatever is required.

If you require lots of fields, I'd consider that a code smell. If you must POST lots of complex data, I'd try posting a JSON doc with the action type as application/json.

@pooranpatel2512 Any update on which direction you took? I'm curious to see how this panned out.

In many server libraries I've worked with in the past, there's this inherent ability to use complex data structures via a special syntax. For example:

color[hue]=123&color[saturation]=34&color[brightness]=98

after being parsed by many query-string parsers becomes:

{
  color: {
    hue: 123,
    saturation: 34,
    brightness: 98
  }
}

I don't believe such syntax is directly a part of the specification for URIs, (I could be wrong there though) but that doesn't mean a server can't infer that, as the specification seems to leave that up to server implementations.

With that in mind, there's no reason you can specify this in your Siren API, since your server would be able to understand a request coming in using that syntax. This would involve no changes to the Siren specification to support.

However, in the example above, it seems like the desire is to treat color as a single field. If that is indeed the case, I don't believe we need to add custom types to Siren. You could use text with a string that has predictable syntax. (which the server will parse) This approach does introduce out-of-band information needed to be known by the client, which is contrary to hypermedia. A solution to that problem would be to add validation to fields. (discussion in #12) Adding a pattern could be used to specify how the string should be formed by the client.