Skip to content

Démarrage

Affordant est un client hypermédia (HATEOAS) orienté affordances. Le serveur indique à votre frontend quelles actions sont disponibles ; votre UI s'affiche à partir de cela, au lieu de redériver les règles d'autorisation côté client.

Installation

sh
npm install affordant

Le cœur a zéro dépendance et fonctionne partout où fetch existe : navigateurs, Node ≥ 18, Deno, Bun, edge workers.

Les trois questions

Chaque interaction se résume à trois appels :

  1. Que me propose le serveur ?can(resource, rel)
  2. Où / comment ?actionFor(resource, rel)
  3. Fais-le.follow(action, init)
ts
import { can, actionFor, follow, type HateoasResource } from 'affordant'

type Order = { id: string; total: number; status: string }
const order: HateoasResource<Order> = await fetch('/orders/8f3a2c').then(r => r.json())

if (can(order, 'cancel')) {
  await follow(actionFor(order, 'cancel')!, {
    token: () => localStorage.getItem('token'), // getter paresseux, lu au moment de la requête
    body: { reason: 'changed my mind' },        // encodé en JSON selon le `accepts` de l'action
  })
}

can et actionFor sont sûrs vis-à-vis de null : passez une ressource null, undefined ou sans _actions et vous obtenez false / null plutôt qu'une erreur levée. Cela les rend sûrs à appeler pendant que les données chargent encore.

Ce que vous y gagnez

  • L'autorisation vit à un seul endroit — le serveur. La présence du lien cancel est la permission. Le frontend ne réimplémente jamais « cet utilisateur peut-il annuler cette commande ? ».
  • Aucune URL ni verbe codé en dur. Le href et la method proviennent de la réponse. Renommez une route côté serveur et chaque client suit.
  • Le bouton suit la réalité. Quand le serveur cesse de proposer une action, can() renvoie false et le contrôle disparaît — sans déploiement du frontend.

Plus que le client

affordant est le client, mais il fait partie d'une petite famille partageant un unique contrat de fil :

Voir les paquets pour la carte complète, ou continuez simplement à utiliser les appels vanilla ci-dessus — ils fonctionnent partout.

Étapes suivantes

Publié sous licence MIT.