Task-Based UI and REST

これは作者の@NaokiTsuchiya氏の了解を得て、日本語の記事を英語にしたものです。

* Orignal text (ja): https://qiita.com/NaokiTsuchiya/items/fe5622639d5f57c172d3
* Translated with www.DeepL.com/Translator (free version)

# Introduction

In this article we will briefly discuss the question "Isn't this hypermedia control? In this article, we will briefly explain the point "Isn't Hypermedia Control?

# Task-Based UI

The following is an example of Task-Based UI taken from Figure 7 of [CQRS Documents by Greg Young](https://cqrs.files.wordpress.com/2010/11/cqrs_documents.pdf).
Each row of the table represents an `Inventory Item`, with the following information: `Name`, `Supplier`, `Active`, and for `Inventory Items` with a check mark in the `Active` column, the fourth column has a Link called `Deactivate`.

![スクリーンショット 2020-12-19 12.06.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129649/99358a71-51df-8f32-12c8-c119829a95d0.png)

If a user follows the `Deactivate` Link of an `Inventory Item`, they will be taken to a screen like the following

![Screenshot 2020-12-19 12.06.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129649/68287c4d-d0dc-d61c-0387-2011be4922ef.png)

The user will be asked to comment on the reason for disabling the item.


As can be seen in [original](https://cqrs.files.wordpress.com/2010/11/cqrs_documents.pdf), the user's intentions are very clear in this sequence of operations and are achieved through software guidance.

This software guidance is called hypermedia control in the Web world, and is a very important element [^hateoas] in REST.

[^hateoas]: one of the four interface constraints to be a hypermedia constraint: Hypermedia as the Engine of Application State (HATEOAS).

# Hypermedia Controls

Hypermedia control refers to the use of hypermedia to control the application state (the state of the client's location in the client-server interaction). The client's position is represented by the URL in the request. The server indicates the next action to be taken by the client by means of a link, and the client transitions between states by means of that link.

Let's take the `Inventory Item` example above.
The application state diagram (ASD) is shown below [^asd]. Squares represent states and arrows represent transitions.
On the ASD, `Figure7` and `Figure8` correspond to the quoted images.

[^asd]: generated from [ALPS](http://alps.io/) at https://github.com/koriym/app-state-diagram

![スクリーンショット 2020-12-19 17.11.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129649/3544cacd-d6d7-7e04-27e8-55399a9322a7.png)

Let's consider that the application represented by ASD exists on the web.
A user enters a URL pointing to `Figure7` into a browser. Then the server returns a page like the following.

![スクリーンショット 2020-12-19 12.06.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129649/99358a71-51df-8f32-12c8-c119829a95d0.png)


From this state, all the user has to do is follow the `Deactivate` link provided by the server.
When the user clicks on the `Deactivate` link, the following page is returned

![スクリーンショット 2020-12-19 12.06.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129649/68287c4d-d0dc-d61c-0387-2011be4922ef.png)

By clicking on the link shown by the server, the application state has moved from `Figure7` to `Figure8`. This is due to hypermedia control🎉.

There are two things a user can do from the `Figure8` state: 1.

1. click `Cancel` to go to `Figure7`.
2. enter a comment and click `Deactivate` to move to the next state.

ASD uses `Figure7` as the destination for transition 2, but the point is that the destination is indicated by the server anyway.
In addition, the state of resources on the server may have changed by the transition of 2.
It is not clear to the user what exactly has changed, but the state of `Figure 7` when it is first accessed is probably different from the state of `Figure 7` after 2.

# Provide it as an API

How can we provide the above experience as an API?
The basic idea is still the same: the server gives you a link or a form, and the user follows it through the state transitions.

`application/json` is the most common API response format, but `application/json` doesn't support hypermedia as a media type, so the client doesn't know where to find the URL.
It is better to use `application/hal+json`[^hal] or `application/vnd.siren+json`[^siren].

[^hal]: http://stateless.co/hal_specification.html
[^siren]: https://github.com/kevinswiber/siren

You can also find articles like the following.
[Representing forms with JSON](/tkawa/items/2414eb954cb700c3a280)
There are also many frameworks that support hypermedia.

- [BEAR.Sunday](https://bearsunday.github.io/index.html)[^sunday].
    - [REST Application Design Implementation Instructions](https://qiita.com/koriym/items/cb6efd0ab2fb8751f9e9)
- [Spring HATEOAS](https://spring.io/projects/spring-hateoas)
    - [Spring HATEOAS - Reference Documentation](https://docs.spring.io/spring-hateoas/docs/current/reference/html/#reference)
- [Laravel HATEOAS](https://github.com/gdebrauwer/laravel-hateoas)

[^sunday]: A resource-oriented application framework

# Greg's change of mind

As noted in [Task-based UI and CQRS](/amashigeseiji/items/3ad45bc08d15ecf7b0a7)
I was quite critical of REST around 2009, perhaps because I understood that REST = CRUD. Here is a quote from one of his tweets

<blockquote class="twitter-tweet"><p lang="en" dir="ltr">watching the REST group discuss CQS is extremely painful.</p>&mdash; Greg Young (@ gregyoung) <a href="https://twitter.com/gregyoung/status/1923868384?ref_src=twsrc%5Etfw">May 26, 2009</a></blockquote> <script async src ="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

However, the following year, he tweeted that REST is CQRS, so it seems that REST is no longer considered CRUD.

<blockquote class="twitter-tweet"><p lang="en" dir="ltr">I used to think RESTand a CQRS based architecture were at odds with each other. This is not true, REST done right is a `CQRS` architecture</p>&mdash; Greg Young (@gregyoung) <a href="https://twitter.com/gregyoung/status/14040334079? ref_src=twsrc%5Etfw">May 15, 2010</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

# DDD and ALPS

I accidentally brought up DDD. I'll write it quickly so it doesn't happen at 5am or something.

As mentioned in @amashigeseiji's article, DDD needs a task-based UI to make sense of operations.
ALPS allows APIs to share their semantics with clients.
Semantics can be assigned to transitions as well as to the content of API responses.

[bengo4com advent calendar](/advent-calendar/2020/bengo4com) The article by @koriym on day 10 has more details.
[Media types and ALPS profiles](/koriym/items/2e928efb2167d559052e)

# Summary

We discussed hypermedia controls using the Task-Based UI from CQRS Documents by Greg Young as an example.
Hypermedia controls themselves are not particularly new. It's something we take for granted in our everyday experience.
But when it comes to APIs, hypermedia control is often lost.
When designing APIs, we should think about state transitions, and by showing links and forms from the server and controlling client state transitions, we can design APIs with the high extensibility of the Web.

### PS

This article has been peer-reviewed by Greg Young as "reasonable (except for some glitches in the translation software)".

この記事はGreg Young氏から「（一部翻訳ソフトの不具合の他は）妥当な内容である」との査読を受けています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3940/cc379cd5-0f32-7a6e-ced6-df9378882a3c.png)