5a. API - Yolino/t211-dbox-fm GitHub Wiki
Résumé coaching 5.a
+ Les choix de conception de l'API sont expliqués sur le Wiki : Ressources exposées, choix de nommage, technologie utilisée… Les noms et conventions utilisés sont cohérents.
+ La documentation de l'API est accessible depuis le Wiki. Elle est claire et bien organisée.
"Pour chaque ressource, une section détaille au moins :
* la description de la ressource
* les endpoints associés et les méthodes pour y accéder
* les éventuels paramètres disponibles
* un exemple de requête
* un exemple de réponse"
+ L'API respecte globalement les principes REST
+ Le groupe peut présenter un exemple fonctionnel de endpoint de l'API (par ex. avec curl). Tous les étudiants peuvent en expliquer le fonctionnement.
+ Le groupe utilise un outil adéquat dédié pour tester son API lors du développement
1. Choix de conception pour l'API
Comme mentionné dans nos choix technologiques, notre API est hybride et utilise deux technologies différentes :
-
GraphQL : permet la majorité des queries de données sous différents formats selon le cas d'utilisation, et l'intégralité des mutations pour les opérations qui modifient l'état de la base de données
-
REST : nous sert pour récupérer les fichiers (audio et images) de manière plus efficace que GraphQL, mais également pour la récupération du programme "radio" par notre station réalisée dans le cadre du projet d'électronique, étant donné que le Raspberry Pi Pico n'a pas de client GraphQL intégré
2a. Documentation de l'API GraphQL
Chaque application possède individuellement son système de query et mutation :
Types
PublicationType
id
: IDtitle
: Stringauthor
: ReportedUserTypecover
: String (URL de l'image de couverture)tag
: TagTypedescription
: StringviewCount
: IntvoteCount
: IntcreatedAt
: DateTimeisBanned
: BooleanvisitorVote
: StringisOwner
: Boolean
ReportedUserType
id
: IDusername
: StringisActive
: BooleanreportCount
: Int
ReportedPublicationType
id
: IDtitle
: Stringauthor
: ReportedUserTypecover
: Stringdescription
: StringisBanned
: BooleanreportCount
: Int
ReportedCommentType
id
: IDpublication
: ReportedPublicationTypeauthor
: ReportedUserTypetext
: StringisBanned
: BooleanreportCount
: Int
SchedulingType
id
: IDpublication
: ReportedPublicationTypetime
: DateTime
TagType
id
: IDname
: StringpublicationSet
: [ReportedPublicationType!]
CommentType
id
: IDpublication
: ReportedPublicationTypeauthor
: ReportedUserTypeparent
: ReportedCommentTypetext
: StringcreatedAt
: DateTimeisBanned
: Boolean
ProfileType
user
: UserTypepublications
: [PublicationType!]comments
: [CommentType!]isSelf
: Boolean
UserType
id
: IDusername
: Stringemail
: StringisActive
: Boolean
PrivilegesType
isLoggedIn
: BooleanisModerator
: Boolean
ReportedContentType
users
: [ReportedUserType]publications
: [ReportedPublicationType]comments
: [ReportedCommentType]totalCount
: Int
PublicationPageType
publications
: [PublicationType!]hasNextPage
: Boolean
Query
schedule(date: Date): [SchedulingType]
• - Renvoie la liste des publications planifiées pour une date donnée.
- Réponse :
[SchedulingType]
- Erreurs :
- Aucune date fournie renvoie tous les éléments planifiés
reporters(reportedId: Int!, contentType: String!): [ReportUnion]
• - Renvoie la liste des rapports pour un contenu donné.
- Réponse :
[ReportUnion]
reportedContent: ReportedContentType
• - Récupère tous les contenus signalés (utilisateurs, publications, commentaires).
- Réponse :
ReportedContentType
bannedContent: ReportedContentType
• - Récupère tous les contenus bannis.
- Réponse :
ReportedContentType
publication(id: Int!): PublicationType
• - Renvoie une publication unique par son ID.
- Réponse :
PublicationType
- Erreurs :
- La publication n'existe pas
- L'utilisateur n'est pas autorisé à consulter une publication bannie
publicationPage(start: Int, count: Int, orderBy: String, author: String): PublicationPageType
• - Renvoie une page paginée de publications selon les critères.
- Réponse :
PublicationPageType
commentsByPublication(publicationId: Int!): [CommentType!]
• - Renvoie tous les commentaires liés à une publication.
- Réponse :
[CommentType!]
publicationLookup(title: String!): [PublicationType!]
• - Recherche les publications contenant un titre donné.
- Réponse :
[PublicationType!]
tags: [TagType]
• - Liste tous les tags disponibles.
- Réponse :
[TagType]
me: PrivilegesType
• - Renvoie les privilèges de l'utilisateur courant.
- Réponse :
PrivilegesType
profile(username: String): ProfileType
• - Renvoie le profil public d'un utilisateur.
- Réponse :
ProfileType
userLookup(name: String!): [UserType!]
• - Recherche des utilisateurs par nom d'utilisateur.
- Réponse :
[UserType!]
Mutation
createPublication(title: String!, cover: Upload, tag: Int!, description: String!, audio: Upload!)
• - Crée une nouvelle publication.
- Paramètres :
title
: Titre de la publicationcover
: Fichier image de couverture (optionnel)tag
: ID du tagdescription
: Description de la publicationaudio
: Fichier audio
- Réponse :
PublicationType
- Erreurs :
- Utilisateur non authentifié
- Le tag n'existe pas
- Format d’image invalide
- Format audio invalide
updatePublication(publicationId: Int!, title: String, description: String, tag: Int, cover: Upload, removeCover: Boolean!)
• - Met à jour une publication existante.
- Paramètres :
publicationId
: ID de la publicationtitle
: Nouveau titre (optionnel)description
: Nouvelle description (optionnel)tag
: Nouveau tag (optionnel)cover
: Nouvelle image de couverture (optionnelle)removeCover
: Indique si la couverture doit être supprimée
- Réponse :
UpdatePublication
- Erreurs :
- Publication introuvable ou non autorisée
- Le tag n'existe pas
deletePublication(publicationId: Int!)
• - Supprime une publication existante.
- Paramètres :
publicationId
: ID de la publication
- Réponse :
DeletePublication
- Erreurs :
- Utilisateur non autorisé
- Publication introuvable
createVote(publicationId: Int!, type: Int!)
• - Crée un vote sur une publication.
- Paramètres :
publicationId
: ID de la publicationtype
: Type de vote (ex: 1 = upvote, -1 = downvote)
- Réponse :
CreateVote
- Erreurs :
- Publication introuvable
- Utilisateur non authentifié
updateVote(publicationId: Int!, type: Int!)
• - Met à jour le type d’un vote existant.
- Paramètres :
publicationId
: ID de la publicationtype
: Nouveau type de vote
- Réponse :
UpdateVote
- Erreurs :
- Aucun vote existant pour cette publication
deleteVote(publicationId: Int!)
• - Supprime un vote d’une publication.
- Paramètres :
publicationId
: ID de la publication
- Réponse :
DeleteVote
- Erreurs :
- Aucun vote à supprimer
createView(publicationId: Int!)
• - Incrémente le compteur de vues d’une publication.
- Paramètres :
publicationId
: ID de la publication
- Réponse :
CreateView
createComment(publication: Int!, text: String!, parent: Int)
• - Crée un commentaire sur une publication.
- Paramètres :
publication
: ID de la publicationtext
: Contenu du commentaireparent
: ID du commentaire parent (optionnel)
- Réponse :
CreateComment
- Erreurs :
- Utilisateur non authentifié
- Publication introuvable
updateComment(commentId: Int!, text: String!)
• - Modifie un commentaire existant.
- Paramètres :
commentId
: ID du commentairetext
: Nouveau texte du commentaire
- Réponse :
UpdateComment
- Erreurs :
- Commentaire introuvable
- Non autorisé
deleteComment(commentId: Int!)
• - Supprime un commentaire existant.
- Paramètres :
commentId
: ID du commentaire
- Réponse :
DeleteComment
- Erreurs :
- Non autorisé à supprimer ce commentaire
createScheduling(publicationId: Int!, time: DateTime!)
• - Programme une publication à une date précise.
- Paramètres :
publicationId
: ID de la publicationtime
: Date et heure de publication
- Réponse :
CreateScheduling
deleteScheduling(schedulingId: Int!)
• - Supprime une planification de publication.
- Paramètres :
schedulingId
: ID de la planification
- Réponse :
DeleteScheduling
createReport(contentType: String!, reportedId: Int!)
• - Signale un contenu (utilisateur, publication ou commentaire).
- Paramètres :
contentType
: Type de contenu (e.g. "user", "publication")reportedId
: ID du contenu signalé
- Réponse :
CreateReport
reviewReport(isSafe: Boolean!, reportType: String!, reportedId: Int!)
• - Marque un signalement comme traité.
- Paramètres :
isSafe
: Si le contenu est jugé acceptablereportType
: Type du rapport (user/publication/comment)reportedId
: ID du contenu signalé
- Réponse :
ReviewReport
unbanContent(bannedId: Int!, contentType: String!)
• - Rétablit un contenu banni.
- Paramètres :
bannedId
: ID du contenucontentType
: Type de contenu
- Réponse :
UnbanContent
createUser(email: String!, password: String!, username: String!)
• - Crée un nouvel utilisateur.
- Paramètres :
email
: Adresse e-mailpassword
: Mot de passeusername
: Nom d'utilisateur
- Réponse :
CreateUser
loginUser(username: String!, password: String!)
• - Connecte un utilisateur.
- Paramètres :
username
: Nom d'utilisateurpassword
: Mot de passe
- Réponse :
LoginUser
logoutUser
• - Déconnecte l'utilisateur actuel.
- Réponse :
LogoutUser
updateUsername(newUsername: String!, password: String!)
• - Met à jour le nom d’utilisateur.
- Paramètres :
newUsername
: Nouveau nompassword
: Mot de passe actuel
- Réponse :
UpdateUsername
updatePassword(currentPassword: String, newPassword: String)
• - Change le mot de passe de l'utilisateur.
- Paramètres :
currentPassword
: Mot de passe actuel (optionnel)newPassword
: Nouveau mot de passe
- Réponse :
UpdatePassword
2b. Documentation de l'API REST
-
GET /audio/{pk}/
- Récupère le fichier audio associé à une publication.
- URL: /audio/{pk}/
- Paramètres d'URL:
- pk: ID de la publication (entier)
- Réponse réussie:
- Code: 200 OK
- Contenu: Flux du fichier audio
- Type de contenu: audio/mpeg
- Réponses d'erreur:
- Code: 404 Not Found
- Contenu: {"detail": "Audio not found"}
- Condition: La publication avec l'ID spécifié n'existe pas
- Code: 403 Forbidden
- Contenu: {"detail": "This Publication has been banned. You can no longer access it"}
- Condition: La publication a été bannie
- Code: 404 Not Found
-
GET /schedule/
- Récupère la liste complète des programmations.
- URL: /schedule/
- Paramètres: Aucun
- Réponse réussie:
- Code: 200 OK
- Contenu: Liste des objets de programmation
- Format:
[{"id": integer, "publication": integer, "time": datetime}, ...]
3. Outils utilisés pour développer et tester l'API
- Frontend : Apollo Client est le module utilisé par le client pour envoyer les queries/mutations et traiter leurs réponses
- Backend : Graphene Django est employé du côté serveur pour définir le schéma GraphQL. Dans le cadre du serveur de développement servi par Django, Graphene nous offre un environnement de test du schéma grâce à GraphiQL, disponible en
localhost:8000/graphql