The granularity of the relationship of links to accuracy in a custom media type?

I have been developing a custom media type for the RESTful API and have studied the types and semantic meaning of some standard link relationships to give my design some control.

To demonstrate the problem, let's say that I have a resource on which I can execute standard methods of reading, changing, deleting, and that I use the idioms HTTP GET, PUT and DELETE respectively to implement these methods.

I could intelligently (re) use the β€œedit” link link (from the IANA Link Registry ) as defined in RFC5023 , which states:

"... The value" edit "indicates that the value of the href attribute is the IRI of the member's record being edited. When it appears inside atom: entry, the IRI href can be used to retrieve, update, and delete the resource represented by this record ...."

Thus, the user agent can understand that the link with the "edit" relationship will allow the resource to be GET, PUT, and DELETEd.

However, this is the problem, if the state of the resource is edited in such a way that the resource now supports only GET and DELETE operations, the "edit" relation is no longer accurate.

To maintain accuracy, I need to either i) OPTION A: specify a different (compound) link relationship that supports only GET and DELETE, or ii) OPTION B: specify separate links for each possible state transfer and use the appropriate ones to indicate allowed state transfers. The latter approach offers accuracy, but looks too verbose.

Alternatively (OPTION C), I could leave the "edit" relationship in place and accept the lack of precision, i.e. the link will pass the semantics of GET, PUT, DELETE, but a user agent trying to execute PUT will be met using HTTP Error '405 - Method not allowed'. However, I am not happy with this approach, as this means that the client is transitioning to a state that is not supported.

So the question is, what is the most reasonable way to balance commonality of relations and accuracy?

+4
source share
3 answers

After some serious investigation, I came to the conclusion that I was trying to solve the wrong problem. Instead of referring to the granularity of the HTTP verb in the definition of Link Relation, the more subtle question is: "Should HTTP idioms (verbs) be combined into Link Relation?".

I used AtomPub as a link on how to do Link Relations (for REST), and it turns out that it was a mistake. In the AtomPub mail archive, Roy Fielding advises that (under REST conditions) the editing approach is incorrect and concludes that this is not necessary. The argument assumes that there are other (HTTP) mechanisms for passing such properties and therefore they do not have a place in the rel attribute.

Other mechanisms in the explicit archive are not explicitly specified, but I suspect that they include the following parameters:

  • Let the user agent try to check the response (2xx or 4xx) or
  • Use OPTIONS to request a resource for permitted operations or
  • Include the "Allow" header in successful GET requests to transfer permitted resource operations to the user agent.

Interestingly, Roy considers the 'Allow' header "a form of hypertext."

In conclusion, the answer to my question is:

"Do not combine HTTP operations with the value" rel "

and

"Use the (provided) HTTP mechanisms to determine permitted resource operations"

Edit: I have to add that there are some special applications of POST as a data receiver, where these rules should bend a little, but then this is a special case.

+2
source

The WRML specification takes an approach in which each link object can have a rel property.

GET /dogs/1 { "links" : { "self" : { "href" : "http://api.example.com/dogs/1 "rel" : "http://api.example.com/relations/self" } } } 

And the client can follow rel url

 GET /relations/self { "name" : "self" "description" : " A reference back to the same object you are currently interacting with" "method" : "GET" } 

The specification really recommends that every rel should have exactly the specified 1 method. This leads to the fact that you very clearly indicate to your customers what they should do and limits the amount of out-of-band knowledge that is required. I personally move on to this because I think there is some value in that some "rel" provide several HTTP methods. Imagine a link for a dog owner

 GET /dogs/1 { "links" : { "self" : { "href" : "http://api.example.com/dogs/1 "rel" : "http://api.example.com/relations/self" } "owner" : { "href" : "http://api.example.com/owner/1 "rel" : "http://api.example.com/relations/owner" } } } 

It would be nice to let the "owner" imply GET and PUT, as these actions are valid actions. In this case, you always need to do a GET before performing the update, so the value when providing this information before retrieving the resource is bad.

So, I think all that said I will vote for OPTION B.

+1
source

Another option is to leave the β€œedit” relationship and allow the consumer who wants to know what they can currently perform on the resource to make a request using the OPTIONS HTTP method, and the server can return a response using the Allow header to specify allowed methods of the resource, given its current state.

This does not give you the availability of the PUT operation without an additional request, but it is pretty "clean" and allows you to use the standard relation and the HTTP mechanism.

0
source

Source: https://habr.com/ru/post/1398615/


All Articles