---
title: "Réseaux sociaux"
description: "Catalogue public des réseaux sociaux et gestion des handles de l'utilisateur (modèle handle + template, URL reconstruite au read)."
---

Les réseaux sociaux d'un utilisateur suivent un modèle **handle + template** : on stocke le `handle` saisi (ex. `HavocKKS`) et l'URL publique est **reconstruite au read** depuis un gabarit par réseau. On ne stocke jamais une URL brute fournie par l'utilisateur (sécurité). Le même bloc `socials` est inline sur `GET /api/auth/me` et sur la page profil web `/@{username}`.

## `GET /api/socials`

Catalogue public des réseaux **actifs**, localisé. Aucun paramètre, aucune pagination (≈ 19 entrées bornées par produit). Tri `(position, id)`.

- **Auth** : aucune.
- **Action** : [ListSocialsAction](../src/Http/Action/Api/Socials/ListSocialsAction.php).

```json
{
  "data": [
    {
      "type": "socials",
      "id":   "instagram",
      "attributes": { "slug": "instagram", "label": "Instagram", "kind": "handle", "position": 10 }
    }
  ],
  "links": { "self": "https://api.example/api/socials" },
  "meta":  { "total": 19 }
}
```

---

## `GET /api/users/me/socials`

Entrées sociales courantes de l'utilisateur authentifié, dans leur ordre d'affichage. Chaque ressource porte le `handle` stocké **et** l'`url` reconstruite.

- **Auth** : requise.
- **Action** : [GetMySocialsAction](../src/Http/Action/Api/Users/Social/GetMySocialsAction.php).

```json
{
  "data": [
    {
      "type": "socials",
      "id":   "instagram",
      "attributes": {
        "slug": "instagram", "label": "Instagram", "kind": "handle",
        "handle": "HavocKKS", "url": "https://www.instagram.com/HavocKKS", "position": 0
      }
    },
    {
      "type": "socials",
      "id":   "website",
      "attributes": {
        "slug": "website", "label": "Site web", "kind": "url",
        "handle": "https://havoc.example.com", "url": "https://havoc.example.com", "position": 1
      }
    }
  ],
  "links": { "self": "https://api.example/api/users/me/socials" },
  "meta":  { "total": 2 }
}
```

---

## `PUT /api/users/me/socials`

Remplace **tout** le jeu de réseaux de l'utilisateur (set complet, idempotent) — pas d'`add`/`remove` granulaires. L'**ordre du tableau = ordre d'affichage** persisté ; une liste vide efface tous les réseaux. Opération atomique (DELETE des réseaux retirés + upsert préservant `created_at` par réseau).

- **Auth** : requise.
- **Action** : [SetMySocialsAction](../src/Http/Action/Api/Users/Social/SetMySocialsAction.php).
- **Corps** : forme aplatie OU JSON:API.

```json
// flat
{ "socials": [
  { "slug": "instagram", "handle": "@HavocKKS" },
  { "slug": "website",   "handle": "https://havoc.example.com/" }
] }

// JSON:API
{ "data": { "attributes": { "socials": [
  { "slug": "instagram", "handle": "@HavocKKS" }
] } } }
```

- **Réponse `200`** : le jeu persisté (handles normalisés, URLs reconstruites) — même forme que `GET /api/users/me/socials`.
- **Erreur `422`** : `source.pointer = "/data/attributes/socials"` + `meta.code` (ex. `users.socials.handleInvalid`) + `meta.invalidEntries`.

---
