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

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 Tuesday, 4 March 2014 16:39:13 UTC