# Ressources, URI et représentations

### Les ressources

Une **ressource** est tout ce qui mérite d'avoir un nom et une adresse : un utilisateur, un dépôt, un livre, un emprunt, le profil de l'utilisateur connecté…

<p class="callout info">Une ressource n'est pas une table SQL. `/user` sur GitHub est une ressource (« moi »), alors qu'elle correspond à une ligne parmi d'autres de la table des utilisateurs. À l'inverse, un emprunt de livre peut réunir des données de plusieurs tables.</p>

### Les URI

Chaque ressource est identifiée par une **URI** (*Uniform Resource Identifier*). L'API de GitHub en donne de bons exemples :

<table id="bkmrk-typeexemplesignifica"><thead><tr><th>Type</th><th>Exemple</th><th>Signification</th></tr></thead><tbody><tr><td>Collection</td><td>`/users`</td><td>Tous les utilisateurs</td></tr><tr><td>Élément</td><td>`/users/thibaudfrichet`</td><td>L'utilisateur `thibaudfrichet`</td></tr><tr><td>Sous-collection</td><td>`/users/thibaudfrichet/repos`</td><td>Les dépôts de `thibaudfrichet`</td></tr><tr><td>Singleton</td><td>`/user`</td><td>L'utilisateur connecté (il n'y en a qu'un)</td></tr></tbody></table>

L'URI désigne **quoi**. C'est la méthode HTTP qui dit **quoi faire** avec. Les règles de nommage sont détaillées au chapitre 5.

```text
GET    /v1/livres/3              ✅ lire le livre 3
DELETE /v1/livres/3              ✅ supprimer le livre 3
GET    /v1/deleteLivre?id=3      ❌ un verbe dans l'URL
```

### Les représentations

Le client ne reçoit jamais la ressource elle-même, mais une **représentation** de son état à un instant donné. Une même ressource peut avoir plusieurs représentations.

Le client indique ce qu'il veut avec le header `Accept`. C'est la **négociation de contenu**. Exemple avec l'API d'une bibliothèque :

**En JSON :**

```bash
curl -H "Accept: application/json" https://api.biblio.example/v1/livres/3
```

```json
{"id": 3, "titre": "Le Petit Prince", "auteur": "Antoine de Saint-Exupéry"}
```

**En XML :**

```bash
curl -H "Accept: application/xml" https://api.biblio.example/v1/livres/3
```

```xml
<livre id="3">
  <titre>Le Petit Prince</titre>
  <auteur>Antoine de Saint-Exupéry</auteur>
</livre>
```

Et si le format demandé n'existe pas, le serveur répond `406 Not Acceptable` :

```bash
curl -i -H "Accept: image/png" https://api.biblio.example/v1/livres/3
```

```http
HTTP/1.1 406 Not Acceptable
```

<p class="callout success">Une représentation, c'est comme une photo : la même personne peut être en couleur ou en noir et blanc, en portrait ou en miniature. La personne, elle, ne change pas.</p>

Dans l'autre sens, c'est le header `Content-Type` qui indique le format du body que le client **envoie**.