REST - Typed resources vs HYDRA classes

281 views Asked by At

From Fielding's article (https://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven):

A REST API should never have “typed” resources that are significant to the client. Specification authors may use resource types for describing server implementation behind the interface, but those types must be irrelevant and invisible to the client. The only types that are significant to a client are the current representation’s media type and standardized relation names. [ditto]

In HYDRA, classes can be documented in the API documentation like this:

supportedClass:
  '@id': 'schema:Event'
    supportedProperty:
      - property:
          '@id': eventName

Isn't it considered a typed resource? There is even a @type field in JSON-LD. I understand the importance of standardized relation names, as they give clients the semantics, the format and constraints necessary to do useful stuff with the resource or property, however by limiting the range of possible relations in the API documentation, we are really declaring types (classes).

Without classes, clients won't know what relations will be present, and coding a client so it knows most relation types (e.g. from schema.org) isn't practical.

What is the exact meaning of this constraint, and how could it be useful in practice? Does HYDRA not respect this?


I'm asking this out of theoretical interest. In practice, I don't care if my HTTP API satisfies all constraints if it is usable.

1

There are 1 answers

0
David Szalai On

I think I get the difference between 'typed resources' (as Fielding calls them), and types or classes defined in media-types like JSON-LD/HYDRA. I'm answering my own question, but please extend/correct it if necessary.


TL;DR my understanding is that this constraint refers to types as predefined representations (or structures) of the resource, and advocates documenting possible relations and media-type processing rules instead of this structure. These relations can still be grouped under 'types', but the representation will not be rigid.


Properties usually have predefined names and understood in the context of its enclosing type. This means that the server/client should agree on this naming convention in order to process these types, and a field named the same in one type as in a different type may have a fully different semantics. It yields a rigid structure for resources.

On the other hand, hypermedia types like JSON-LD do not use properties in a common way. They instead use some embedded information (@context) to define the semantics of the properties, which can be other entities, value objects, references, etc...

By processing a resource with a given hypermedia type, the properties are translated to some well-defined relations, usually defined in a vocabulary. This means that the same relation can be reused for multiple types, e.g. a name field in a Person and Book could refer to the https://schema.org/name relation between them and value objects (e.g. simple string names).

This decouples the client from the server by allowing them to use a common vocabulary for relation types, and by defining processing rules for a media type, so it is advisable to preprocess the resource before using it directly in its serialized format (as you might not know how it is returned).

For example:

{
  "@context": "http://schema.org/",
  "@type": "Person",
  "@id": "http://srv.org/users/1",
  "name": "Jane Doe",
  "telephone": "(425) 123-4567",
  "url": "http://www.janedoe.com"
}

is the same resource as

{
  "@context": {
    "a": "http://schema.org/name",
    "b": "http://schema.org/telephone",
    "c": {
      "@id": "http://schema.org/url",
      "@type": "@id"
    }
  },
  "@type": "http://schema.org/Person",
  "@id": "http://srv.org/users/1",
  "a": "Jane Doe",
  "b": "(425) 123-4567",
  "c": "http://www.janedoe.com"
}

or even as

[
  {
    "@id": "http://srv.org/users/1",
    "@type": [
      "http://schema.org/Person"
    ],
    "http://schema.org/name": [
      {
        "@value": "Jane Doe"
      }
    ],
    "http://schema.org/telephone": [
      {
        "@value": "(425) 123-4567"
      }
    ],
    "http://schema.org/url": [
      {
        "@id": "http://www.janedoe.com"
      }
    ]
  }
]