L'autorisation, exprimée une seule fois
La présence d'un lien encode la permission. Le serveur décide à chaque réponse ; le frontend s'affiche à partir de can() et ne redérive jamais vos règles d'autorisation.
L'hypermédia (HATEOAS) est le niveau de maturité REST que la plupart des équipes n'atteignent jamais. Affordant vous y amène — le serveur déclare les actions qu'il propose ; votre UI s'affiche à partir d'elles, sans réimplémenter l'autorisation dans le frontend.
Votre frontend ne construit jamais d'URL, ne choisit jamais de verbe HTTP, ne duplique jamais une règle d'autorisation. Il pose trois questions :
import { can, actionFor, follow } from 'affordant'
if (can(order, 'cancel')) { // 1. Que me propose le serveur ?
await follow(actionFor(order, 'cancel')!, { // 2. Où / comment ? 3. Fais-le.
token: () => localStorage.getItem('token'),
body: { reason: 'changed my mind' },
})
}Si le backend cesse de proposer une action — non autorisé, mauvais état, fonctionnalité désactivée — le bouton disparaît. Aucun déploiement du frontend.
Le serveur déclare ces mêmes affordances une seule fois, en conditionnant chacune à l'état faisant autorité. Quand when est faux, le rel n'est jamais émis — donc can() renvoie faux côté client.
import { resource } from '@affordant/server'
resource(order)
.self(route('orders.show', order.id))
.action('cancel', route('orders.cancel', order.id), {
method: 'POST',
when: caller.id === order.ownerId && order.status !== 'shipped',
})
.build()Un seul contrat, jamais deux implémentations à garder synchronisées. Voir les paquets pour toute la famille.