summaryrefslogtreecommitdiffstatshomepage
path: root/www/content/essays/hypermedia-driven-applications.md
blob: c7d102469d501eef39a6d36d7308542b72e0a9bc (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
+++
title = "Hypermedia-Driven Applications"
date = 2022-02-06
updated = 2022-10-18
[taxonomies]
author = ["Carson Gross"]
tag = ["posts"]
+++

## Genesis

> thesis: MPA - multi-page application
>
> antithesis: SPA -  single-page application
>
> synthesis: HDA - hypermedia-driven application
>
> \-\-[@htmx_org](https://twitter.com/htmx_org/status/1490318550170357760)

## The Hypermedia-Driven Application Architecture

The **Hypermedia Driven Application (HDA)** architecture is a new/old approach to building web applications.  It combines
the simplicity & flexibility of traditional Multi-Page Applications (MPAs) with the better user experience of 
[Single-Page Applications](https://en.wikipedia.org/wiki/Single-page_application) (SPAs).

The HDA architecture achieves this goal by extending the existing HTML infrastructure of the web to allow hypermedia
 developers to create more powerful hypermedia-driven interactions.
 
Following the REST notion of architectural [constraints](https://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm),
two such constraints characterize the HDA architecture: 

* An HDA uses *declarative, HTML-embedded syntax* rather than imperative scripting to achieve better front-end interactivity

* An HDA interacts with the server **in terms of hypermedia** (i.e. HTML) rather than a non-hypermedia format (e.g. JSON)

By adopting these two constraints, the HDA architecture stays within the original 
[REST-ful](https://developer.mozilla.org/en-US/docs/Glossary/REST) architecture of the web in a way that the SPA architecture
does not.  

In particular, HDAs continue to use [Hypermedia As The Engine of Application State (HATEOAS)](@/essays/hateoas.md), whereas
most SPAs abandon HATEOAS in favor of a client-side model and data (rather than hypermedia) APIs.

## An Example HDA fragment

Consider the htmx [Active Search](@/examples/active-search.md) example:

```html
<h3> 
  Search Contacts 
  <span class="htmx-indicator"> 
    <img src="/img/bars.svg"/> Searching... 
   </span> 
</h3>
<input class="form-control" type="search" 
       name="search" placeholder="Begin Typing To Search Users..." 
       hx-post="/search" 
       hx-trigger="keyup changed delay:500ms, search" 
       hx-target="#search-results" 
       hx-indicator=".htmx-indicator">

<table class="table">
    <thead>
    <tr>
      <th>First Name</th>
      <th>Last Name</th>
      <th>Email</th>
    </tr>
    </thead>
    <tbody id="search-results">
    </tbody>
</table>
```

This is a UX pattern that would typically be associated with an SPA: as the user types, after a slight pause, search 
results will populate the result table below.  However, in this case, it is being achieved entirely within HTML,
in a manner consonant with HTML.

This example effectively demonstrates the essential characteristic of an HDA:

* The front end of the feature is specified entirely in  declarative htmx attributes, directly in HTML

* The interaction with the server is done via HTTP and HTML: an HTTP `POST` request is sent to the server, HTML is 
  returned by the server and htmx inserts this HTML into the DOM

## Scripting In An HDA

[Code-On-Demand](https://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm#sec_5_1_7) is an optional
constraint of the original REST-ful architecture of the web.

Similarly, the HDA architecture has a final, optional constraint:

* Code-On-Demand (i.e. scripting) should, as much as is practical, be done *directly in* the primary hypermedia

This addresses the concern regarding Code-On-Demand that Roy Fielding mentions in his thesis:

>  However, (Code-On-Demand) also reduces visibility, and thus is only an optional constraint within REST.

By embedding Code-On-Demand (scripts) directly in HTML, visibility is enhanced, satisfying the 
[Locality of Behavior](@/essays/locality-of-behaviour.md) software design principle.

Three approaches to scripting that satisfy this third constraint are [hyperscript](https://hyperscript.org), 
[AlpineJS](https://alpinejs.dev) and [VanillaJS](http://vanilla-js.com/) (when embedded directly on HTML elements).

Here is an example of each of these approaches:

```html
<!-- hyperscript -->
<button _="on click toggle .red-border">
  Toggle Class
</button>

<!-- Alpine JS -->
<button @click="open = !open" :class="{'red-border' : open, '' : !open}">
  Toggle Class
</button>

<!-- VanillaJS -->
<button onclick="this.classList.toggle('red-border')">
  Toggle Class
</button>
```

In an HDA, hypermedia (HTML) is the primary medium for building the application, which means that:

* All communication with the server is still managed via HTTP requests with hypermedia (HTML) responses
* Scripting is used mainly to enhance the *front-end experience* of the application

Scripting augments the existing hypermedia (HTML) but does not *supersede* it or subvert the fundamental REST-ful
architecture of the HDA.

## HDA-style libraries

The following libraries allow developers to create HDAs:

* <https://htmx.org>
* <https://unpoly.com/>
* <https://piranha.github.io/twinspark-js/>
* <https://hotwire.dev>
* <https://hyperview.org/> (a mobile hypermedia!)

The following scripting libraries, when used appropriately, complement the HDA approach:

* <https://hyperscript.org>
* <https://alpinejs.dev/>
* <http://vanilla-js.com/> (embedded directly in HTML)

## Conclusion

The HDA architecture is a synthesis of two preceding architectures: the original Multi-Page Application (MPA) architecture
 and the (relatively) newer Single-Page Application architecture.  

It attempts to capture the advantages of both: the simplicity and reliability of MPAs, with a 
[REST-ful Architecture](https://developer.mozilla.org/en-US/docs/Glossary/REST) that uses 
[Hypermedia As The Engine Of Application State](@/essays/hateoas.md), while providing a better user experience, on par
with SPAs in many cases.