3

I'm wondering how best to model in a HATEOAS based API links that allow the client to set parameters. E.g. imagine a search response that returns a list of producst and then refinements that can be performed on them:

{
    "results" : {
        ...
    }
    "refinements" : {
        "Size" : {
            "links" : {
               "extra small" : "/products?size=xs",
               "medium" : "/products?size=m"
            }
        }, 
        Price : {
            links: {
                "greater than" : "/products?priceGreaterThan=aValue",
                "less than" : "/products?priceLesshan=aValue",
                "between" : "/products?priceLesshan=aValue&priceGreaterThan=aValue"
            }
        }
    }
}

The size refinements seem straight forwards but the price refinements require the client to pass a value. How is this typically represented in a HATEOAS link?

Sutty1000
  • 1,379
  • 1
  • 12
  • 15

3 Answers3

5

I highly recommend that, when using hypermedia, you use a hypermedia enabled media type. There are many JSON based media types out there that support form-like interactions.

Here is an example using JSON Hyper-Schema. It behaves just like an HTML Form with method="get".


/product

HTTP/1.1 200 OK
Content-Type: application/json
Link: </schema/product-list>; rel="describedby"

{
  results: [ ... ]
}

/schema/product-list

HTTP/1.1 200 OK
Content-Type: application/schema+json

{
  "$schema": "http://json-schema.org/draft-04/hyper-schema#",
  "links" : [
    {
      "rel": "search",
      "href": "/products",
      "schema": {
        "type": "object",
        "properties": {
          "size": { "enum": ["xs", "m"] },
          "priceGreaterThan": { "type": "number" },
          "priceLessThan": { "type": "number" }
        }
      }
    }
  ]
}

A generic client can build all of the links from your example and more with this schema. Other examples of media types with similar capabilities are Siren, Hydra, and of course HTML.

2

Your going to hate(oas) this answer but my interpretation of the original idea would be:

<form method="get" action="products">
    <input type="number" name="priceGreaterThan"/>
    <input type="submit"/>
</form>

You have given full interpretable information on what to pass and how to pass it in Hypermedia format.

In fact before i get a million down votes let me back myself up with some Roy Fielding quotes:

A truly RESTful API looks like hypertext.

and

Think of it in terms of the Web. How many Web browsers are aware of the distinction between an online-banking resource and a Wiki resource? None of them. They don’t need to be aware of the resource types. What they need to be aware of is the potential state transitions — the links and forms — and what semantics/actions are implied by traversing those links.

and

the media type tells the client either what method to use (e.g., anchor implies GET) or how to determine the method to use (e.g., form element says to look in method attribute).

Ewan
  • 70,664
  • 5
  • 76
  • 161
  • 1
    Good answer: references to (json) media types with form support would make it stronger. – VoiceOfUnreason May 14 '18 at 19:52
  • or as RF is asked directly in the same blog post comments: "...I just want to know if there are any known media types besides HTML that is suitable for REST interfaces. As I see it, HTML is not ideal for an API intended to be used by a machine." Roy remains silent on this question – Ewan May 14 '18 at 20:04
  • oh wait, i tell a lie "...using microformats of HTML, RDF in N3 or XML, or even SVG..." RF – Ewan May 14 '18 at 20:06
  • Hypertext =/=> HTML. See Roy Fielding's comment here : https://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven#comment-718 There are much more convenient media types than `text/html` to convey this, IMO. – guillaume31 May 15 '18 at 12:24
  • @guillaume31 I think that's the same page i am quoting from. I think it would be more accurate to say HTML is a form of hypertext. Other forms (allegedly) exist, but it seems hard to name any which are json based. presumably you can define you own media type ewans/json or whatever which has the equivalent of forms but in json rather than xml – Ewan May 15 '18 at 12:38
2

Other than the ones mentioned by Jason, Collection+JSONs Query Templates may be a good fit here though I'm not a huge fan of its verbosity.

Perhaps more elegantly, HAL uses URI templates to describe parameterized links:

{
    "_links": {

        "ea:find": {
            "href": "/orders{?id}",
            "templated": true
        }
    }
}
guillaume31
  • 8,358
  • 22
  • 33