Re: ISSUE-31: Are Operations violating REST's uniform interface constraint?

100% Agree Markus. I’m a little slammed right now and will likely be silent for a days. But I think a “Hydra Pet Store” might be a great sample app to test out some idea between both the server and the client. I’ll put up some text cases and idea before I start writing up code. But again, Likely a week or two out.


Ryan-

+-----------------------------------------------+
    Ryan J. McDonough
    http://damnhandy.com
    http://twitter.com/damnhandy






On Mar 4, 2014, at 11:38 AM, Markus Lanthaler <markus.lanthaler@gmx.net> wrote:

> On Tuesday, March 04, 2014 1:02 PM, Ryan J. McDonough wrote:
>> 
>> Markus,
>> 
>> Just wanted to summarize this as this thread may be getting off-track a
>> bit.
> 
> Thanks a lot for doing this Ryan. I think this helps to reframe the
> discussion.
> I'll let the other thread die but if there's something in your other mail
> (which I of course read) that you want me to comment on, just tell me.
> 
> 
>> I know Mark has bailed on this effort, but I believe he was trying
>> to point out that even without hydra:status and hydra:returns,
>> hydra:Operation still potentially violates the architectural
>> constraints as it allows clients to potentially make assumptions about
>> the behavior of the request which may or may not be true. I also agree
>> with Mark to a certain degree.
>> 
>> My point in this long thread was that if you need typed messages, it
>> should be in the message itself rather than around the message.
> 
> Yeah, I think I understand your point but am still confused about what Mark
> was trying to say. He seems to say exactly the opposite: 
> 
>  <> :POST <http://example.org/my-endpoint> .
> 
>  it is declaring that it accepts POST requests to that URL, and that is
>  the entire contract. If it wants to create things (as opposed to
>  annotate things, or "extending a database"), that is its prerogative
>  as an implementation and it needn't indicate that to the client a
>  priori (201 is after the fact, of course), **nor require the client
>  indicate which one it wants/expects** (as that would be tunnelling
>  ala SOAP).
> 
>  http://lists.w3.org/Archives/Public/public-hydra/2013Nov/0065.html
>  (my highlighting)
> 
> 
>> From my
>> perspective, there's little value in  having a CreateResourceOpertaion
>> for a POST if the actual business function my application is carrying
>> out doesn't result in the creation of a new resource.
> 
> Fully agreed.
> 
> 
>> Here's two versions of the same message from beginning of this
>> thread:
>> 
>> POST /my/cart/my/cart HTTP/1.1
>> Host: example.com
>> Content-Type: application/ld+json
>> 
>> {
>>    "@context": "http://example.com/cart",
>>    "@type": "AddItemToCartRequest",
>>    "productId": "1789",
>>    "productVarientId": "1641",
>>    "quantity": 2
>> }
>> 
>> and
>> 
>> POST /my/cart/my/cart HTTP/1.1
>> Host: example.com
>> Content-Type: application/x-www-form-urlencoded
>> 
>> productId=1789&productVarientId=1641&quantity=2
>> 
>> The main difference between the two examples is the media type being
>> used. Functionally, they say the same thing. Without a doubt, the JSON-
>> LD version is more descriptive, yet the application/x-www-form-
>> urlencoded approach is in use on most sites today.  What makes the
>> second approach "RESTful" is that the application/x-www-form-urlencoded
>> request was generated from an HTML form. The browser was told what to
>> do next by the current state of where they are now. That's REST.
> 
> I think the main problem I have is seeing the difference between an HTML
> form
> 
> <form method="post" action="/my/cart/my/cart">
>  <p>Add the following product to the shopping cart</p>
>  <label>Product ID: <input type="number" name="productId"></label>
>  <label>Variant ID: <input type="number" name="productVarientId"></label>
>  <label>Quantity: <input type="number" name="quantity"></label>
>  <button type="submit">Add</button>
> </form>
> 
> and the corresponding Hydra description
> 
> {
>  "@id": "/my/cart/my/cart",
>  "operation": {
>    "@type": "AddTheProductToTheShoppingCartOperation",
>    "method": "POST",
>    "expects": {
>      "supportedProperty": [
>        { "property": "vocab:productId" },
>        { "property": "vocab:productVarientId" },
>        { "property": "vocab:quantity" }
>      ]
>    }
>  }
> }
> 
> 
>> It's not about CRUD, it's about describing links and and instructing
>> clients on how to format and transmit those messages over the correct
>> HTTP method at runtime.
> 
> I also fully agree with this statement. This is in fact what drove the
> design of Hydra. I understand that the introduction of those predefined CRUD
> operations was more than counterproductive.
> 
> 
>> This is the role I was hoping that Hydra operations would play. But it
>> seems that there's also a belief that REST follows strict CRUD model,
>> which just wrong.
> 
> No, you clearly misunderstood me on that.
> 
> 
>> REST is not about using the uniform interface to
>> enable CRUD. If you're seeing both of the examples above as SOAP-like
>> because they use a structured message format over POST to alter the
>> state of other resources, then there is really not much more I can
>> offer here.
>> 
>> But if I'm mistaken and that your perspective is not that REST is CRUD
>> and you don't view POST as an anathema, then I may have a few
>> suggestions.
> 
> What I've tried to say in regard to POST (I realize that I should have been
> more explicit) is that you lose a number of *sometimes* important properties
> when you go from PUT to POST. Idempotency allows you to simply repeat failed
> requests (e.g. because the wifi went down) whereas you can't do that with
> POST. That's all.
> 
> I'm very interested in your suggestions.
> 
> Do you think it would be helpful to model the e-commerce API we used in our
> discussion in more detail and describe it with Hydra as an exercise on the
> mailing list? This question is obviously not just for Ryan but also for
> everyone else on the list :-)
> 
> 
> Thanks again Ryan,
> Markus
> 
> 
> --
> Markus Lanthaler
> @markuslanthaler

Received on Wednesday, 5 March 2014 19:52:47 UTC