RE: My opinion about hydra vocabulary

Hi László,

You forgot to CC the group. I've forwarded your mail. Whenever you send a
mail to the group, you will get a copy back. If you don't get a copy back,
you forgot to CC the group :-)

On Tuesday, January 28, 2014 1:46 PM, László Lajos Jánszky wrote:
>
> Thanks the feedback!
> Huh where to start. :-)

>> HAL+JSON is not very suitable for the kind of services we are talking
about
>> in the context of Hydra. HAL more or less just provides an envelope for
JSON
>> representations to add a couple of hyperlinks. You can achieve exactly
the
>> same by using HTTP Link headers and keep your ordinary JSON. With Hydra
and
>> JSON-LD in contrast, all properties are unambiguously identified by URLs,
>> not just links.
> 
> By HAL+JSON with link relations it is a bit trickier to describe type and
> linked data connections, but it's not impossible:
> 
>     {
>         _embedded: {
>             name: {
>                 value: "László",
>                 _links: {
>                     type: {href: "http://my.api/docs/User/name"},
>                     profile: {href: "http://schema.org/name"}
>                 }
>             }
>         }
>     }
>
> or with external file:

[...]

Yeah, that's possible but hardly useful and not standardized. Not many
applications would understand that.


>> The "knows" here is the link relation type. As the name suggests, it
defines
>> the type of relationship these two resources stand to each other. What
>> "Resource Method" does that link call? I don't know. Now I think you were
>> thinking more of something like
>> 
>>   /an-issue --[ comments ]--> /comments
> 
> There are standardized link relations on the iana page. For example by
> edit you can always use PUT, by self you can use always GET, by
> service you can use always GET, and your client will be hardcoded to
> interpret that link as the entry point to a REST service.

Well, you can *always* GET/PUT/POST etc. regardless of the link relation.
The link relation by itself however doesn't tell you much about the HTTP
methods. When you say by "edit you can always use PUT" than you are probably
speaking about the AtomPub protocol. Other application domain
protocols/media types may use the edit link relation differently.


> So by link
> relations you have to teach your client every link relation you use in
> your REST service. For example by comments, you can use a collection
> relation and maybe your custom "comments" relation too. After that the
> comments page uses an item relation to every single comment, etc... So
> the link relation depends on the resource and on the context in where
> the resource is... For example a single comment has an item relation
> in the context of the comments collection, and has  a self relation in
> the context of itself. Btw this is the logic of the HAL+JSON
> documents. JSON-LD has different logic. :-)
> 
>   {
>     "@context": "http://www.w3.org/ns/hydra/context.jsonld",
>     "@id": "#comments",
>     "@type": "Link",
>     "title": "Comments",
>     "supportedOperations": [
>       {
>         "@type": "CreateResourceOperation",
>         "title": "Creates a new comment",
>         "method": "POST",
>         "expects": "#Comment",
>         "returns": "#Comment",
>       }
>     ]
>   }
> 
> With HAL+JSON and link relations your JSON-LD document can be
> described as something like this:
> 
>   {
>     "title": "Comments",
>     _links: {
>         create: {
>             href: "/issue/24/comments",
>             "title": "Creates a new comment",
>             "expects": {href: "http://my.api/docs/issue/comments/comment"}
>         },
>         self: {href: "/issue/24/comments"},
>         type: {href: "http://my.api/docs/issue/comments"}
>     }
>   }

The thing is that this isn't standardized at all. Thus you would have to
hardcode your client against such an API. There's no standardized "create"
link relation, neither does HAL define what "expects" stands for. 


> It does not use returns, because the HAL+JSON always describes itself,
> so if it uses the create link, it will POST the input fields, and the

Which input fields?


> response will contain the type of the "returns" part. The field
> descriptions can come from the documentation of the "expects" part, or
> can be given by each link, for example:
> 
>   {
>     "title": "Comments",
>     _links: {
>         create: {
>             href: "/issue/24/comments",
>             "title": "Creates a new comment",
>             "fields": {
>                 title: {type: "string", min: 0, max: 127},
>                 description: {type: "markdown", min: 10, max: 2000}
>             }
>         },
>         self: {href: "/issue/24/comments"},
>         type: {href: "http://my.api/docs/issue/comments"}
>     }
>   }

Can you point me to the spec where "fields" is described? Don't get me wrong
but you can of course make up whatever JSON representations you want but
just because a property is called "_links" doesn't make it HAL. The point
I'm trying to get across is that if the HAL spec doesn't define these
things, you can't rely on them. If you do, there's no point in claiming to
rely on HAL as you don't. That's not a criticism towards HAL. HAL is fine
but it solves different problems. It is much simpler than JSON-LD and
Hydra.. whether that's a good thing depends on your use case. To paraphrase
Einstein, the solution you choose should be as simple as possible, but not
simpler.


>> Currently there are not a full standard by link relations and almost
>> nothing about how should we describe input fields by complex links.
>> These are just examples of usage. I am currently working on an
>> application which uses these examples, and after that with many
>> refactoring maybe I will be able to describe documentation as well...

Oh I see. I'm wondering why you mention HAL than instead of Siren which has
most of this stuff already built in!?


> Maybe it is possible to merge our approaches, maybe not, but I am sure
> we can learn from each other.

I'm sure we will


> At least I learned how to describe a
> linked data connection in HAL+JSON from your JSON-LD examples...
> 
>> You mean instead of using IRI templates you would move the parameters
>> into the description of operations? How would you describe a URL
>> template like this in that case:
>> 
>>   /users-{lastname]-{id}/
> 
> Nope. I meant, that if I am right you describe the queryString part
> with your IRI templates, about something like this:
> 
> new IRITemplate({
>     template: "/users/{user-id}/comments?sort={sort-type}",
>     mappings: [
>         new IriTemplateMapping({
>             variable: "user-id",
>             property: "docs/user/id",
>             required: true
>         }),
>         new IriTemplateMapping({
>             variable: "sort-type",
>             property: "docs/users/user/comments/params/sort-type",
>             required: false
>         })
>     ]
> })

Yes


> I would rather separate the URL.path from the URL.queryString, and use
> the path to indentify resources and the queryString to describe
> resource modifiers, resource filters.

The main reason why I did that is because it is already standardized as
RFC6570 [1]. What advantages does it have to separate them?


> I am currently working on how to
> describe these variables, I have currently just a vague thoughts about
> this question, an ad-hoc example:
> 
> CommentsMeta = {
>     path: "/users/{User.id}/comments",
>     properties: {
>         "{Comment.id}": "{Comment}"
>     },
>     methods: {
>         GET: {
>             features: {
>                 sortable: [
>                     {
>                         variable: "sort",
>                         source: {
>                             "{Comment.id}": {
>                                 title: {
>                                     comparator: "string"
>                                 },
>                                 creationTime: {
>                                     comparator: "dateTime"
>                                 }
>                             }
>                         },
>                         required: true
>                     }
>                 ]
>             }
>         }
>     }
> }

I have to say this looks much more complicated to me and I struggle to see
what you gain by doing so.


> and by link url creation:
> 
> new Url({
>     path: "/users/24/comments",
>     features: {
>         sortable: {
>             title: true
>         }
>     }
> }) 

I don't understand this snippet.


> So overall, I am still working on a stable rest documentation format,
> if I am done, I'll let you know...

I'm looking forward to read it. Keep us posted.


Cheers,
Markus


[1] http://www.rfc-editor.org/rfc/rfc6570.txt


--
Markus Lanthaler
@markuslanthaler

Received on Tuesday, 28 January 2014 14:53:46 UTC