Adding Swagger

This commit is contained in:
2026-03-29 23:56:11 +02:00
parent fce91fa465
commit fe1bcc0ff7
11 changed files with 1883 additions and 16 deletions
+130
View File
@@ -0,0 +1,130 @@
const swaggerJsdoc = require('swagger-jsdoc');
const fs = require('fs');
const path = require('path');
const yaml = require('js-yaml');
// Fonction pour charger tous les fichiers YAML du dossier swagger
const loadSwaggerFiles = () => {
const swaggerDir = path.join(__dirname, '../swagger');
const files = fs.readdirSync(swaggerDir).filter(file => file.endsWith('.yaml'));
const merged = { paths: {}, components: { schemas: {} } };
files.forEach(file => {
try {
const content = fs.readFileSync(path.join(swaggerDir, file), 'utf8');
const doc = yaml.load(content);
// Fusionner les paths
if (doc.paths) {
Object.assign(merged.paths, doc.paths);
}
// Fusionner les schemas
if (doc.components && doc.components.schemas) {
Object.assign(merged.components.schemas, doc.components.schemas);
}
} catch (error) {
console.error(`Erreur lors du chargement de ${file}:`, error);
}
});
return merged;
};
const swaggerDefinitions = loadSwaggerFiles();
const options = {
definition: {
openapi: '3.0.0',
info: {
title: 'Adastra API',
version: '1.0.0',
description: 'Adastra API Documentation - Express.js API with Sequelize (MySQL) and Mongoose (MongoDB)',
contact: {
name: 'Julien Gautier',
email: 'jgautier.webdev@gmail.com',
},
},
servers: [
{
url: 'http://localhost:3201',
description: 'Development server',
},
{
url: 'http://localhost:3200',
description: 'Local development server',
},
{
url: 'https://api.example.com',
description: 'Production server',
},
],
components: {
securitySchemes: {
bearerAuth: {
type: 'http',
scheme: 'bearer',
bearerFormat: 'JWT',
description: 'JWT Bearer token authentication',
},
apiKeyAuth: {
type: 'apiKey',
in: 'header',
name: 'x-api-key',
description: 'API Key authentication',
},
},
schemas: {
Error: {
type: 'object',
properties: {
error: {
type: 'string',
},
message: {
type: 'string',
},
statusCode: {
type: 'integer',
},
},
},
...swaggerDefinitions.components.schemas,
},
},
paths: swaggerDefinitions.paths,
tags: [
{
name: 'Articles',
description: 'Article management endpoints',
},
{
name: 'Clans',
description: 'Clan management endpoints',
},
{
name: 'Members',
description: 'Member management endpoints',
},
{
name: 'Users',
description: 'User management endpoints',
},
{
name: 'Products',
description: 'Product management endpoints',
},
{
name: 'Hero Wars',
description: 'Hero Wars game data endpoints',
},
],
},
// Les définitions sont chargées depuis les fichiers YAML
apis: [],
};
const swaggerSpec = swaggerJsdoc(options);
module.exports = swaggerSpec;
+366
View File
@@ -0,0 +1,366 @@
paths:
/api/v2/articles:
get:
summary: Récupère la liste paginée des articles
description: Retourne une liste paginée de tous les articles. L'authentification est optionnelle.
tags:
- Articles
parameters:
- in: query
name: page
schema:
type: integer
default: 1
description: Numéro de page
- in: query
name: limit
schema:
type: integer
default: 20
description: Nombre d'articles par page
- in: query
name: search
schema:
type: string
description: Terme de recherche pour les articles
responses:
'200':
description: Liste des articles récupérée avec succès
content:
application/json:
schema:
type: object
properties:
articles:
type: array
items:
$ref: '#/components/schemas/Article'
articlesCount:
type: integer
'400':
description: Erreur de validation
'500':
description: Erreur serveur
post:
summary: Crée un nouvel article
description: Crée un nouvel article avec les données fournies. Authentification requise.
tags:
- Articles
security:
- bearerAuth: []
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- article
properties:
article:
type: object
required:
- title
- description
- body
properties:
title:
type: string
example: "Titre de l'article"
description:
type: string
example: "Description courte"
body:
type: string
example: "Contenu complet de l'article"
tagList:
type: array
items:
type: string
example: ["tag1", "tag2"]
responses:
'201':
description: Article créé avec succès
content:
application/json:
schema:
type: object
properties:
article:
$ref: '#/components/schemas/Article'
'400':
description: Données invalides
'401':
description: Non authentifié
'422':
description: Erreur de validation des données
/api/v2/articles/feed:
get:
summary: Récupère le fil d'actualité des articles
description: Retourne les articles des utilisateurs suivis par l'utilisateur authentifié
tags:
- Articles
security:
- bearerAuth: []
parameters:
- in: query
name: page
schema:
type: integer
default: 1
description: Numéro de page
- in: query
name: limit
schema:
type: integer
default: 20
description: Nombre d'articles par page
responses:
'200':
description: Fil d'actualité récupéré avec succès
content:
application/json:
schema:
type: object
properties:
articles:
type: array
items:
$ref: '#/components/schemas/Article'
articlesCount:
type: integer
'401':
description: Non authentifié
'500':
description: Erreur serveur
/api/v2/articles/{slug}:
get:
summary: Récupère un article par son slug
description: Retourne les détails complets d'un article spécifique
tags:
- Articles
parameters:
- in: path
name: slug
required: true
schema:
type: string
description: Le slug unique de l'article
responses:
'200':
description: Article récupéré avec succès
content:
application/json:
schema:
type: object
properties:
article:
$ref: '#/components/schemas/Article'
'404':
description: Article non trouvé
'500':
description: Erreur serveur
put:
summary: Met à jour un article
description: Met à jour un article existant. Seul l'auteur peut modifier son article. Authentification requise.
tags:
- Articles
security:
- bearerAuth: []
parameters:
- in: path
name: slug
required: true
schema:
type: string
description: Le slug unique de l'article
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- article
properties:
article:
type: object
properties:
title:
type: string
description:
type: string
body:
type: string
tagList:
type: array
items:
type: string
responses:
'200':
description: Article mis à jour avec succès
content:
application/json:
schema:
type: object
properties:
article:
$ref: '#/components/schemas/Article'
'401':
description: Non authentifié
'403':
description: Vous n'êtes pas autorisé à modifier cet article
'404':
description: Article non trouvé
'422':
description: Erreur de validation des données
delete:
summary: Supprime un article
description: Supprime un article existant. Seul l'auteur peut supprimer son article. Authentification requise.
tags:
- Articles
security:
- bearerAuth: []
parameters:
- in: path
name: slug
required: true
schema:
type: string
description: Le slug unique de l'article
responses:
'200':
description: Article supprimé avec succès
'401':
description: Non authentifié
'403':
description: Vous n'êtes pas autorisé à supprimer cet article
'404':
description: Article non trouvé
'500':
description: Erreur serveur
/api/v2/articles/{slug}/favorite:
post:
summary: Ajoute un article aux favoris
description: Ajoute un article à la liste des favoris de l'utilisateur authentifié
tags:
- Articles
security:
- bearerAuth: []
parameters:
- in: path
name: slug
required: true
schema:
type: string
description: Le slug unique de l'article
responses:
'200':
description: Article ajouté aux favoris avec succès
content:
application/json:
schema:
type: object
properties:
article:
$ref: '#/components/schemas/Article'
'401':
description: Non authentifié
'404':
description: Article non trouvé
'500':
description: Erreur serveur
delete:
summary: Retire un article des favoris
description: Retire un article de la liste des favoris de l'utilisateur authentifié
tags:
- Articles
security:
- bearerAuth: []
parameters:
- in: path
name: slug
required: true
schema:
type: string
description: Le slug unique de l'article
responses:
'200':
description: Article retiré des favoris avec succès
content:
application/json:
schema:
type: object
properties:
article:
$ref: '#/components/schemas/Article'
'401':
description: Non authentifié
'404':
description: Article non trouvé
'500':
description: Erreur serveur
components:
schemas:
Article:
type: object
properties:
slug:
type: string
description: Identifiant unique de l'article (généré à partir du titre)
example: "mon-premier-article"
title:
type: string
description: Titre de l'article
example: "Mon Premier Article"
description:
type: string
description: Description courte de l'article
example: "Description courte pour le résumé"
body:
type: string
description: Contenu complet de l'article
example: "Contenu complet de l'article..."
tagList:
type: array
items:
type: string
description: Liste des tags associés à l'article
example: ["tag1", "tag2"]
author:
type: object
properties:
username:
type: string
image:
type: string
bio:
type: string
following:
type: boolean
description: Informations de l'auteur de l'article
createdAt:
type: string
format: date-time
description: Date/heure de création de l'article
example: "2024-01-15T10:30:00Z"
updatedAt:
type: string
format: date-time
description: Date/heure de la dernière mise à jour
example: "2024-01-15T10:30:00Z"
favorited:
type: boolean
description: Indique si l'article est mis en favori par l'utilisateur authentifié
favoritesCount:
type: integer
description: Nombre de fois que cet article a été ajouté aux favoris
example: 5
+242
View File
@@ -0,0 +1,242 @@
paths:
/api/v3/clans:
get:
summary: Récupère la liste de tous les clans
description: Retourne une liste de tous les clans. L'authentification est optionnelle.
tags:
- Clans
parameters:
- in: query
name: page
schema:
type: integer
default: 1
description: Numéro de page
- in: query
name: limit
schema:
type: integer
default: 20
description: Nombre de clans par page
- in: query
name: search
schema:
type: string
description: Terme de recherche pour les clans
responses:
'200':
description: Liste des clans récupérée avec succès
content:
application/json:
schema:
type: object
properties:
clans:
type: array
items:
$ref: '#/components/schemas/Clan'
clansCount:
type: integer
'400':
description: Erreur de validation
'500':
description: Erreur serveur
post:
summary: Crée un nouveau clan
description: Crée un nouveau clan avec les données fournies
tags:
- Clans
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- clan
properties:
clan:
type: object
required:
- name
properties:
name:
type: string
example: "Mon Clan"
description:
type: string
example: "Description du clan"
level:
type: integer
example: 5
server:
type: string
example: "EU"
responses:
'201':
description: Clan créé avec succès
content:
application/json:
schema:
type: object
properties:
clan:
$ref: '#/components/schemas/Clan'
'400':
description: Données invalides
'422':
description: Erreur de validation des données
'500':
description: Erreur serveur
/api/v3/clans/{clanId}:
get:
summary: Récupère les détails d'un clan
description: Retourne les détails complets d'un clan spécifique. Authentification requise.
tags:
- Clans
security:
- bearerAuth: []
parameters:
- in: path
name: clanId
required: true
schema:
type: integer
description: L'ID unique du clan
responses:
'200':
description: Clan récupéré avec succès
content:
application/json:
schema:
type: object
properties:
clan:
$ref: '#/components/schemas/Clan'
'401':
description: Non authentifié
'404':
description: Clan non trouvé
'500':
description: Erreur serveur
put:
summary: Met à jour un clan
description: Met à jour les informations d'un clan. Authentification requise.
tags:
- Clans
security:
- bearerAuth: []
parameters:
- in: path
name: clanId
required: true
schema:
type: integer
description: L'ID unique du clan
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- clan
properties:
clan:
type: object
properties:
name:
type: string
description:
type: string
level:
type: integer
server:
type: string
responses:
'200':
description: Clan mis à jour avec succès
content:
application/json:
schema:
type: object
properties:
clan:
$ref: '#/components/schemas/Clan'
'401':
description: Non authentifié
'404':
description: Clan non trouvé
'422':
description: Erreur de validation des données
'500':
description: Erreur serveur
delete:
summary: Supprime un clan
description: Supprime un clan. Authentification requise.
tags:
- Clans
security:
- bearerAuth: []
parameters:
- in: path
name: clanId
required: true
schema:
type: integer
description: L'ID unique du clan
responses:
'200':
description: Clan supprimé avec succès
'401':
description: Non authentifié
'403':
description: Vous n'êtes pas autorisé à supprimer ce clan
'404':
description: Clan non trouvé
'500':
description: Erreur serveur
components:
schemas:
Clan:
type: object
properties:
id:
type: integer
description: Identifiant unique du clan
name:
type: string
description: Nom du clan
example: "Mon Clan"
description:
type: string
description: Description du clan
level:
type: integer
description: Niveau du clan
example: 5
server:
type: string
description: Serveur du clan
example: "EU"
membersCount:
type: integer
description: Nombre de membres du clan
example: 30
foundedAt:
type: string
format: date-time
description: Date de création du clan
createdAt:
type: string
format: date-time
description: Date/heure de création du clan
updatedAt:
type: string
format: date-time
description: Date/heure de la dernière mise à jour
+270
View File
@@ -0,0 +1,270 @@
paths:
/api/v3/members:
get:
summary: Récupère la liste de tous les membres
description: Retourne une liste paginée de tous les membres. Authentification requise.
tags:
- Members
security:
- bearerAuth: []
parameters:
- in: query
name: page
schema:
type: integer
default: 1
description: Numéro de page
- in: query
name: limit
schema:
type: integer
default: 20
description: Nombre de membres par page
- in: query
name: clanId
schema:
type: integer
description: Filtrer les membres par clan
- in: query
name: search
schema:
type: string
description: Terme de recherche pour les membres
responses:
'200':
description: Liste des membres récupérée avec succès
content:
application/json:
schema:
type: object
properties:
members:
type: array
items:
$ref: '#/components/schemas/Member'
membersCount:
type: integer
'401':
description: Non authentifié
'400':
description: Erreur de validation
'500':
description: Erreur serveur
post:
summary: Crée un nouveau membre
description: Crée un nouveau membre du clan. Authentification requise.
tags:
- Members
security:
- bearerAuth: []
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- member
properties:
member:
type: object
required:
- userId
- clanId
properties:
userId:
type: integer
example: 1
clanId:
type: integer
example: 1
role:
type: string
enum: ["member", "officer", "leader"]
default: "member"
example: "member"
joinedAt:
type: string
format: date-time
responses:
'201':
description: Membre créé avec succès
content:
application/json:
schema:
type: object
properties:
member:
$ref: '#/components/schemas/Member'
'400':
description: Données invalides
'401':
description: Non authentifié
'422':
description: Erreur de validation des données
'500':
description: Erreur serveur
/api/v3/members/{memberId}:
get:
summary: Récupère les détails d'un membre
description: Retourne les détails complets d'un membre spécifique. Authentification requise.
tags:
- Members
security:
- bearerAuth: []
parameters:
- in: path
name: memberId
required: true
schema:
type: integer
description: L'ID unique du membre
responses:
'200':
description: Membre récupéré avec succès
content:
application/json:
schema:
type: object
properties:
member:
$ref: '#/components/schemas/Member'
'401':
description: Non authentifié
'404':
description: Membre non trouvé
'500':
description: Erreur serveur
put:
summary: Met à jour un membre
description: Met à jour les informations d'un membre (rôle, date d'adhésion, etc.). Authentification requise.
tags:
- Members
security:
- bearerAuth: []
parameters:
- in: path
name: memberId
required: true
schema:
type: integer
description: L'ID unique du membre
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- member
properties:
member:
type: object
properties:
role:
type: string
enum: ["member", "officer", "leader"]
joinedAt:
type: string
format: date-time
responses:
'200':
description: Membre mis à jour avec succès
content:
application/json:
schema:
type: object
properties:
member:
$ref: '#/components/schemas/Member'
'401':
description: Non authentifié
'404':
description: Membre non trouvé
'422':
description: Erreur de validation des données
'500':
description: Erreur serveur
delete:
summary: Supprime un membre
description: Supprime un membre du clan. Authentification requise.
tags:
- Members
security:
- bearerAuth: []
parameters:
- in: path
name: memberId
required: true
schema:
type: integer
description: L'ID unique du membre
responses:
'200':
description: Membre supprimé avec succès
'401':
description: Non authentifié
'403':
description: Vous n'êtes pas autorisé à supprimer ce membre
'404':
description: Membre non trouvé
'500':
description: Erreur serveur
components:
schemas:
Member:
type: object
properties:
id:
type: integer
description: Identifiant unique du membre
userId:
type: integer
description: ID de l'utilisateur associé
user:
type: object
description: Informations de l'utilisateur
properties:
id:
type: integer
username:
type: string
email:
type: string
image:
type: string
clanId:
type: integer
description: ID du clan
clan:
type: object
description: Informations du clan
properties:
id:
type: integer
name:
type: string
level:
type: integer
role:
type: string
description: Rôle du membre dans le clan
enum: ["member", "officer", "leader"]
example: "member"
joinedAt:
type: string
format: date-time
description: Date d'adhésion au clan
createdAt:
type: string
format: date-time
description: Date/heure de création du membre
updatedAt:
type: string
format: date-time
description: Date/heure de la dernière mise à jour
+209
View File
@@ -0,0 +1,209 @@
# Template pour ajouter une nouvelle ressource Swagger
Utilisez ce fichier comme base pour documenter les routes d'une nouvelle ressource.
```yaml
paths:
/api/v1/articles:
get:
summary: Récupère la liste des articles
description: Retourne une liste paginée de tous les articles
tags:
- Articles
parameters:
- in: query
name: page
schema:
type: integer
default: 1
description: Numéro de page
- in: query
name: limit
schema:
type: integer
default: 10
description: Nombre d'éléments par page
responses:
'200':
description: Articles récupérés avec succès
content:
application/json:
schema:
type: object
properties:
data:
type: array
items:
$ref: '#/components/schemas/Article'
total:
type: integer
'400':
description: Erreur de validation
'500':
description: Erreur serveur
post:
summary: Crée un nouvel article
description: Crée un nouvel article avec les données fournies
tags:
- Articles
security:
- bearerAuth: []
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- title
- content
properties:
title:
type: string
example: "Titre de l'article"
content:
type: string
example: "Contenu de l'article"
tags:
type: array
items:
type: string
responses:
'201':
description: Article créé avec succès
content:
application/json:
schema:
$ref: '#/components/schemas/Article'
'400':
description: Données invalides
'401':
description: Non authentifié
/api/v1/articles/{id}:
get:
summary: Récupère un article par ID
tags:
- Articles
parameters:
- in: path
name: id
required: true
schema:
type: integer
description: ID de l'article
responses:
'200':
description: Article récupéré avec succès
content:
application/json:
schema:
$ref: '#/components/schemas/Article'
'404':
description: Article non trouvé
put:
summary: Met à jour un article
tags:
- Articles
security:
- bearerAuth: []
parameters:
- in: path
name: id
required: true
schema:
type: integer
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
title:
type: string
content:
type: string
tags:
type: array
items:
type: string
responses:
'200':
description: Article mis à jour avec succès
content:
application/json:
schema:
$ref: '#/components/schemas/Article'
'404':
description: Article non trouvé
delete:
summary: Supprime un article
tags:
- Articles
security:
- bearerAuth: []
parameters:
- in: path
name: id
required: true
schema:
type: integer
responses:
'200':
description: Article supprimé avec succès
'404':
description: Article non trouvé
components:
schemas:
Article:
type: object
properties:
id:
type: integer
title:
type: string
content:
type: string
author:
type: string
tags:
type: array
items:
type: string
createdAt:
type: string
format: date-time
updatedAt:
type: string
format: date-time
```
## Instructions
1. **Créer un nouveau fichier YAML** dans `src/swagger/` :
```bash
touch src/swagger/articles.yaml
cp src/swagger/template.yaml src/swagger/articles.yaml
```
2. **Modifier le fichier** pour adapter les routes à votre ressource
3. **Redémarrer le serveur** :
```bash
npm run local
```
4. **Consulter les docs** : http://localhost:3200/api-docs
## Conventions
- **Un fichier YAML par ressource** (users.yaml, articles.yaml, products.yaml, etc.)
- **Réutiliser les schémas** : utilisez `$ref: '#/components/schemas/User'` au lieu de redéfinir
- **Utiliser les tags** pour regrouper les routes (Articles, Users, Products, etc.)
- **Utiliser les chemins corrects** : `/api/v1/...`, `/api/v2/...`, etc.
- **Documenter les réponses d'erreur** : 400, 401, 404, 500
+230
View File
@@ -0,0 +1,230 @@
paths:
/api/v1/user:
get:
summary: Récupère le profil de l'utilisateur connecté
description: Retourne les informations du profil de l'utilisateur authentifié
tags:
- Users
security:
- bearerAuth: []
responses:
'200':
description: Profil utilisateur récupéré avec succès
content:
application/json:
schema:
type: object
properties:
user:
$ref: '#/components/schemas/User'
'401':
description: Authentification requise
'500':
description: Erreur serveur
put:
summary: Met à jour le profil de l'utilisateur connecté
description: Permet à l'utilisateur authentifié de mettre à jour les informations de son profil
tags:
- Users
security:
- bearerAuth: []
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
user:
type: object
properties:
username:
type: string
email:
type: string
firstname:
type: string
lastname:
type: string
phone:
type: string
licence:
type: string
poids:
type: number
image:
type: string
bg_image:
type: string
password:
type: string
role:
type: string
responses:
'200':
description: Profil utilisateur mis à jour avec succès
content:
application/json:
schema:
type: object
properties:
user:
$ref: '#/components/schemas/User'
'401':
description: Authentification requise
'500':
description: Erreur serveur
/api/v1/users/login:
post:
summary: Authentifie un utilisateur
description: Authentifie un utilisateur avec email et mot de passe, retourne un JWT
tags:
- Users
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- user
properties:
user:
type: object
required:
- email
- password
properties:
email:
type: string
format: email
password:
type: string
responses:
'200':
description: Authentification réussie, JWT retourné
content:
application/json:
schema:
type: object
properties:
user:
$ref: '#/components/schemas/User'
'422':
description: Email ou mot de passe manquant/incorrect
'500':
description: Erreur serveur
/api/v1/authenticate:
get:
summary: Authentification par clé API
description: Authentifie un utilisateur/application avec une clé API dans les headers
tags:
- Users
security:
- apiKeyAuth: []
responses:
'200':
description: Authentification réussie
content:
application/json:
schema:
type: object
properties:
user:
$ref: '#/components/schemas/User'
application:
type: object
'401':
description: Clé API invalide ou non autorisée
'500':
description: Erreur serveur
/api/v1/users:
post:
summary: Crée un nouvel utilisateur
description: Crée un nouvel utilisateur avec les données fournies
tags:
- Users
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- user
properties:
user:
type: object
required:
- email
- firstname
- lastname
- password
properties:
username:
type: string
email:
type: string
format: email
firstname:
type: string
lastname:
type: string
phone:
type: string
licence:
type: string
poids:
type: number
password:
type: string
responses:
'200':
description: Utilisateur créé avec succès
content:
application/json:
schema:
type: object
properties:
user:
$ref: '#/components/schemas/User'
'422':
description: Données invalides
'500':
description: Erreur serveur
components:
schemas:
User:
type: object
properties:
id:
type: string
username:
type: string
email:
type: string
format: email
firstname:
type: string
lastname:
type: string
phone:
type: string
licence:
type: string
poids:
type: number
image:
type: string
bg_image:
type: string
role:
type: string
token:
type: string
description: JWT Bearer token pour les requêtes authentifiées