APIs ❤️ HTML

“Hypertext is a computer-supported medium for information in which many interlinked documents are displayed with their links on a high-resolution computer screen.”
— Jeffrey Conklin

2024-10-06 - Benoit AVERTY

Histoire et état de l’art d’une application web…​

Il y a longtemps

NavigateurNavigateurServeurServeurGET /document.htmlContent-Type: text/html

Plus récemment…​

NavigateurNavigateurServeurServeurApplication enfin utilisableGET /document.htmlContent-Type: text/html, Content-Length: 0 (ou presque)GET /<script>.jsContent-Type: text/javascript, Content-Length: 1GoGET /api/trucContent-Type: application/jsonlooploop

Et en ce moment

NavigateurNavigateurServeurServeurJe peux déjà voir des choses, oufMais je peux cliquer seulement maintenantGET /document.htmlContent-Type: text/htmlGET /<script>.jsContent-Type: text/javascript, Content-Length: 1GoloopServer-side Rendering

Est-ce satisfaisant ?

(non)

  • Beaucoup de JS téléchargé

  • Beaucoup de JS écrit !

  • Des frameworks complexes (complexité dès le début d’un projet. Va-t-on la rentabiliser ?)

Mais pourquoi autant de JS ?

  • Votre code appelle une API, parse la réponse, applique des règles métier…​

  • Un framework Synchronise les données avec l’UI, gère le routing, l’historique…​

Bref, il y a un browser dans votre browser

Tout ça pour éviter une petite perte de contrôle au clic sur un lien

Et s’il existait un autre moyen ?

techno mystere

Données

{
  "connections": [
    { "name": "BDD de prod",
      "url":  "jdbc:postgres://root@mabdd.dmz.company:5432/postgres" },
    { "name": "BDD de staging",
      "url":  "jdbc:postgres://root@mabdd-staging.dmz.company:5432/postgres" },
    { "name": "Local",
      "url":  "jdbc:postgres://postgres@localhost:5432/public" }
  ]
}

Données + Métadonnées

<h2>Connections</h2>
<table>
    <thead><tr><th>Name</th><th>URL</th></tr></thead>
    <tbody>
        <tr><td>BDD de prod</td><td>jdbc:postgres://root@mabdd.dmz.company:5432/postgres</td></tr>
        <tr><td>BDD de staging</td><td>jdbc:postgres://root@mabdd-staging.dmz.company:5432/postgres</td></tr>
        <tr><td>Local</td><td>jdbc:postgres://postgres@localhost:5432/postgres</td></tr>
    </tbody>
</table>

Connections

NameURL
BDD de prodjdbc:postgres://root@mabdd.dmz.company:5432/postgres
BDD de stagingjdbc:postgres://root@mabdd-staging.dmz.company:5432/postgres
Localjdbc:postgres://postgres@localhost:5432/postgres

Hypertext markup language

HTML sait aussi exprimer les actions disponibles pour intéragir avec les données

<h2>Connections</h2>
<table>
    <thead><tr><th>Name</th><th>URL</th><th></th></tr></thead>
    <tbody>
        <tr>
            <td><a href="/connections/1">BDD de prod</a></td>
            <td>jdbc:postgres://root@mabdd.dmz.company:5432/postgres</td>
            <td>
                <form method="post" action="/connections/1">
                    <button type="submit" name="delete">x</button>
                    <button type="submit" name="connect">Connect</button>
                </form>
            </td>
        </tr>
        <tr>
            <td><a href="/connections/1">BDD de staging</a</td>
            <td>jdbc:postgres://root@mabdd-staging.dmz.company:5432/postgres</td>
            <td>
                <form method="post" action="/connections/2">
                    <button type="submit" name="delete">x</button>
                    <button type="submit" name="connect">Connect</button>
                </form>
            </td>
        </tr>
        <tr>
            <td><a href="/connections/1">Local</a></td>
            <td>jdbc:postgres://postgres@localhost:5432/postgres</td>
            <form method="post" action="/connections/3">
                <button type="submit" name="connect">Connect</button>
            </form>
        </tr>
    </tbody>
</table>

Hypertext = Livre dont vous êtes le héros

NameURL
BDD de prod jdbc:postgres://root@mabdd.dmz.company:5432/postgres
BDD de staging jdbc:postgres://root@mabdd-staging.dmz.company:5432/postgres

Hypermedia + Client Hypermedia

 = Client Hypermedia

100% générique

Out-of-band information

Client spécifiqueServeurDonnées JSONDoc, Contrat d'interface, connaissance métier...

No out-of-band information

no oob information

Ok, mais pourquoi personne ne le fait alors ?

  • Seuls les liens et les formulaires sont intéractifs

  • Un navigateur ne sait faire que du GET et du POST

  • Il ne sait que recharger la page entière

Les possibilités de HTML sont limitées par rapport aux possibilités de HTTP 😞

HTMX

HTMX est une bibliothèque dont le but est de lever ces limitations de HTML.

Avec HTMX on code du HTML « étendu »

  • Déclaratif

  • Data / UI / Intéractions colocalisées

    « Locality of behavior »

HTMX

htmx cycle

À quoi ça ressemble ?

<form
    hx-on="submit"
    hx-post="/connections"
    hx-include="find input"
    hx-target="#result"
    hx-swap="beforeend"
>
    <input type="text" name="url" />
    <input type="text" name="password" />
</form>
<table id="result">
</table>

Démo time !

Une API ?

Avantages

  • Moins de JS ⇒ 📈 UX

  • Langage backend au choix ⇒ 📈 DX

  • Facile à débugger depuis les devtools ⇒ 📈 DX

    Grâce au principe de « Locality of behavior »
  • Découplage entre les différents « composants » ⇒ 📈 DX

  • Pas d’information "Out-of-band"

    Grâce au client 100% générique

Quand développer une application Hypermedia ?

Et quand préférer une api de données (JSON)

  • Qui consomme ma donnée ? Des humains ou des programmes ?

  • Est-ce que ma valeur ajoutée / ma complexité se trouve côté front ?

  • Est-ce que j’ai réfléchi à faire du micro-frontend ?

Concrêtement je fais comment ?

Merci

feedback

slides disponibles sur http://benoitaverty.com/confs