RE: Step by step resource editing

Hi Kev,

and sorry for the delay. Comments inline.

On Monday, September 08, 2014 7:46 PM, Kev Kirkland wrote:
> I'm having trouble figuring out how to implement a scenario with a
> Hydra API. I'll describe the problem in terms of an ecommerce site
> rather than my situation (creating a visualisation) as it will be more
> familiar to most people.
> 
> Imagine you are going through the checkout process for an order. You
> need to enter payment details and an address. In pseudo HTTP the
> process would look something like this: 

Abbreviating this a bit:

> 1) Request: payment form
> 2) Response: send payment form as html
> 3) Request: save payment
> 4) Response: payment stored, redirect to address page
> 5) Request: address form
> 6) Response: address form html
> 7) Request: send address
> 
> When we go through the process we are seeing two html forms being
> presented one after the other - the payment form then the address
> form. I can't find a way to do this in Hydra though. The payment form
> can be opened with something like the following:
> 
> "supportedOperation": [
>   {
>     "method": "POST",
>     "label": "Make payment",
>     "expects": "vocab:PaymentDetails",
>     "returns": "vocab:AddressDetails"
>   }
> ]
> 
> The problem is with the next phase - the server accepts the payment
> and redirects to the address page - but how do you signal to the Hydra
> client that you want the address form displayed? In other words how
> would you do steps 5 and 6 in the same way you'd do it in html
> (displaying a form after you've filled in another form).

UIs are not a primary concern of Hydra. It has been designed for Web APIs where you typically deal with just raw data. That being said, you can do the same that you did with the payment form. I would, probably, model this slightly differently though. Assuming we have an order resource. I would simply embed the operations in its representation

  {
    ...
    "@type": "Order",
    "operation": {
      "method": "POST",
      "label": "Make payment",
      "expects": "vocab:PaymentDetails",
      "returns": "vocab:Order"
    }
  }

As soon as the user made the payment, you replace that operation with an operation to set the address. An alternative would be to model this as a workflow so that you explicitly state what the next valid step(s) are. Something like:

  OrderWorkflow
     --- firstStep --> WorkflowStep [Payment]
            ---> describes operation to execute this step
    on success returns new WorkflowStep [Address]

It might actually be interesting to integrate something like that into Hydra. I created ISSUE-70 [1] so that we don't forget this.


> After the payment is submitted to the server (step 3) the Hydra client
> would follow the HTTP 303 redirect in the response and get the
> contents of the empty address page (/checkout/1/address-form), but how
> would the client know it needs to prompt the Hydra client for more
> information rather than just display the empty address form (using the
> SupportedClass 'vocab:AddressDetails')?

Your client would need to be aware of the process or, alternatively, you could use something like the "workflow pattern" I described above. The advantage is that it is completely generic so your client would work for many different scenarios, not just ordering stuff.


> One option might be to only have one supported operation on the
> vocab:AddressDetails (a POST operation) that signals to the client the
> only option is to do a form POST? This doesn't sound very attractive
> though - it's expecting the client to behave in a 'magic' way to a
> certain set of conditions. It feels like there should be a way to say
> 'display the vocab:AddressDetails SupportedClass as a form' rather
> than the default option of having it displayed as a static page.

Yeah, I fully agree. That's a heuristic at best. But since you talk about user interfaces, it seems as a human is in control anyway, right? If that's the case, I would simply return the order and add the next valid operation to it. The client can then render the order with the registered payment information and show a button to add the address. It could also have two buttons at the beginning, one for the address, one for the payment, if the order in which those operations are invoked doesn't matter.


> In broader terms it's a case of building up a Resource through several
> steps (an order checkout in this example). 'Wizards' work in a similar
> way. Some of those steps can involve routing (following the ecommerce
> example - does the user want gift wrapping options?), so it's not easy
> to load the whole process into one form post (with one
> SupportedClass).

How do you find the workflow stuff I proposed above?


> Any ideas on how to solve this would be much appreciated. I'm building
> a Hydra Javascript client which mimics a Single Page Web Application,
> so it would be good to make the process match user expectations (e.g.
> make the Hydra API mimic the Amazon checkout process rather than
> changing the checkout process to work around Hydra).

Awesome! Do you already have something you can share with us? Btw. it would be great if you could join the Hydra W3C Community Group [2], steps to do so are described at

   http://www.hydra-cg.com/#community

This helps us to avoid surprises in case we transfer Hydra to a W3C WG for standardization in the future.


Thanks,
Markus


[1] https://github.com/HydraCG/Specifications/issues/70
[2] http://www.w3.org/community/hydra


--
Markus Lanthaler
@markuslanthaler

Received on Tuesday, 16 September 2014 18:44:47 UTC