2

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.

David Szalai
  • 2,363
  • 28
  • 47
  • 1
    Jorn Wildt wrote a nice blog post on [this matter](http://soabits.blogspot.com/2012/04/restful-resources-are-not-typed.html) – Roman Vottner Oct 31 '18 at 10:43
  • Thanks, just read it. It seems that his understanding is similar to mine in some way. I think that from the usability side, it is isomorphic to have a generic media-type with varying vocabularies (JSON-LD and schema.org) or have a domain-specific media-type (vCard). Just the 'type' is encoded somewhere else. I'd say it boils down to personal preferences what to use. For me, hydra is preferred due to the uniform interface if I write an API spanning multiple domains. It can later support specific media types if required. Gonna read the referenced articles in that post. – David Szalai Oct 31 '18 at 13:07
  • 1
    The core point of this blog post or Fieldings statement is, that clients should not deduce the type of a resource from its name (i.e. `/api/customers`) but instead use content-negotiation to inform a server that a client is able to process the following media-types and the server should return the information in a representation understood by the client. Fielding also states that the focus in REST architecture should be on specifying media-types and meaningful link-relation names rather than on overengeneering URIs – Roman Vottner Oct 31 '18 at 13:15
  • That's right, that also comes from the fact that uris are transparent, and even the uri structure is not known in advance, so it is not possible anyways. Link relations should document what is the range of a URI when dereferenced, I just wanted to note that it can be done by referencing a specific media-type (vCard) - Jorn Wildt seems to prefer this -, or by referencing a type from a vocabulary (schema.org/CreditCard) in case of json-ld. It was the second case that bugged me, as a vocabulary 'type' is a type (or it seemed first, that's what my answer tries to resolve). – David Szalai Oct 31 '18 at 13:41

1 Answers1

1

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"
      }
    ]
  }
]
David Szalai
  • 2,363
  • 28
  • 47