ZEP-30 : Elaboration de l'API des forums

a marqué ce sujet comme résolu.
Cartouche Valeurs
ZEP 30
Titre Elaboration de l'API des forums
Révision 1
Date de création 9 mai 2015
Dernière révision 9 mai 2015
Type Feature
Statut Acceptée

Contexte

Nouvelle ZEP fille pour la ZEP-02 (ZEP-2 consacrée à l'élaboration d'une API au sens large). Cette nouvelle ZEP a pour objectif d'élaborer la spécification de l'API des forums.

Si vous ne voulez pas connaitre tous les détails techniques mais que vous voulez avoir une bonne vision d'ensemble de ce que proposera la mise en oeuvre de cette ZEP, vous pouvez lire seulement les deux premières sections, "Fonctionnalités" et "Schémas".

Fonctionnalités

Méthode URL Fonctionnalité
Forums
GET /api/forums/ Liste tous les forums
POST /api/forums/ Crée un forum**
GET /api/forums/:id Récupère un forum
PUT /api/forums/:id Edite un forum**
Sujets
GET /api/sujets Liste tous les sujets d’un forum
GET /api/membre/sujets Liste tous les sujets du membre authentifié*
GET /api/membres/:membre/sujets Liste tous les sujets d'un membre
GET /api/tags/:tag/sujets Liste tous les sujets d'un tag
POST /api/sujets Crée un sujet*
GET /api/sujets/:sujet Récupère un sujet
PUT /api/sujets/:sujet Edite un sujet*
Tags
GET /api/forums/tags Liste tous les tags
GET /api/forums/tags/:tag Récupère un tag
Messages
GET /api/sujets/:sujet/messages Liste les messages d'un sujet
GET /api/membre/messages Liste les messages du membre authentifié*
GET /api/membres/:membre/messages Liste les messages d'un membre
POST /api/sujets/:sujet/messages Crée un message dans un sujet*
GET /api/sujets/:sujet/messages/:message Récupère un message
PUT /api/sujets/:sujet/messages/:message Edite un message*
POST /api/sujets/:sujet/messages/:message/like Like un message*
DELETE /api/sujets/:sujet/messages/:message/like Retire le like sur un message*
POST /api/sujets/:sujet/messages/:message/dislike Dislike un message*
DELETE /api/sujets/:sujet/messages/:message/dislike Retire le dislike sur un message*
POST /api/sujets/:sujet/messages/:message/alert Alerte un message*

* : Il faut être authentifié

** : Il faut appartenir au staff

Schémas

Forum

Colonne Type Description
pk long Identifiant du forum
title String Titre du forum
subtitle String Sous-titre du forum
slug String Slug du forum
category Category Catégorie parente du forum
position_in_category Integer Position du forum

Sujet

Colonne Type Description
pk long Identifiant du sujet
title String Titre du sujet
subtitle String Sous-titre du sujet
slug String Slug du sujet
forum Forum Forum parent du forum
author User Auteur du sujet
last_message Post Dernier message du sujet
pubdate Date Date de publication du sujet
is_solved Boolean Sujet marqué comme résolu
is_locked Boolean Sujet marqué comme verrouillé
is_sticky Boolean Sujet marqué en post-it
tags Array Tag Tags d'un sujet

Message

Colonne Type Description
pk long Identifiant du message
topic Topic Sujet parent du message
author User Auteur du message
editor User Editeur du message
text String Contenu du message en Markdown
text_html String Contenu du message en Html
text_hidden String Texte affiché si le message est masqué
like Integer Nombre de like sur un message
dislike Integer Nombre de dislike sur un message
pubdate Date Date de publication du message
update Date Date de mise à jour du message
position Interger Position du message
is_visible Boolean Le message est visible ou non
is_useful Boolean Le message a été marqué utile
+8 -0
Fonctionnalité Méthode URL
Liste des sujets d'un forum GET /api/categories/:id/forums/:id/sujets/
Afficher les informations d'un sujet GET /api/categories/:id/forums/:id/sujets/:id/
Editer un sujet PUT /api/categories/:id/forums/:id/sujets/:id/

* : Inclus la création des tags dans le titre du sujet.

** : Touche un autre module que le module des forums.

Andr0

Est-il obligatoire de fournir tous les paramètres listés pour toucher à la ressource ?
Ex. : dois-je obligatoirement renseigner la catégorie d'un forum pour lister les sujets de ce dernier ?

Pardon si la réponse est plus loin dans la ZEP… Elle est très longue… Quel boulot tu fais Andr0, je suis arrivé ici après avoir lu le sujet de la ZEP MPs, et je dois dire : chapeau bas.

Modif. :

Je sais que l'approche REST consiste à spécifier le chemin de la ressource dans l'URL mais je les trouve longues pour les sujets, encore plus pour les messages. Sachant en plus que, techniquement les identifiants sont séquentiels à travers les forums. Je ne sais donc pas si c'est très pertinent de spécifier un chemin qui ne sert à rien en fait. Est-ce que la question vous semble légitime ? Si oui, qu'est-ce que vous proposeriez ? L'approche REST est-elle stricte sur ce point ?

Je viens de voir ça, du coup je donne mon avis : c'est trop long. En plus ça oblige à connaître certains paramètres que l'on ne possède pas forcément à priori. Ex. : imaginons que l'API notif pointe vers un nouveau message du forum, il est probable qu'elle ne fournira que l'id de ce dit message (scénario purement fictif, elle pourrait très bien tout fournir).

J'ai aussi une suggestion :
Ne serait-il pas possible d'implémenter une méthode qui permette de déterminer les liens entre des messages ? Il doit être possible de détecter les liens qui pointent vers un autre message du forum et d'enregistrer ces messages dans un champs (ou plutôt une autre table mais qu'importe) puis de les rendre avec l'API.

Une telle fonctionnalité permettrait à des applications de "contextualisé" au mieux. On peut imaginer des boutons pour afficher en popup les messages cités/liés par exemple (dans le cas d'une application smartphone).

Du coup ça donnerait ça :

Messages

Colonne Type Description
pk long Identifiant du message
topic Topic Sujet parent du message
author User Auteur du message
editor User Editeur du message
text String Contenu du message en Markdown
text_html String Contenu du message en Html
text_hidden String Texte affiché si le message est masqué
like Integer Nombre de like sur un message
dislike Integer Nombre de dislike sur un message
pubdate Date Date de publication du message
update Date Date de mise à jour du message
position Interger Position du message
is_visible Boolean Le message est visible ou non
is_useful Boolean Le message a été marqué utile
related Array Post Liste des messages cités / liés

Andr0

+0 -0

Bonjour,

Jolie spécification :) , toutes mes félicitations.

J'ai une remarque à propos des catégories… est-ce réellement utile ?

Si on regarde cela alourdi toute la structures des urls (sauf si justement on décide de les faire sauté dans les urls) et de base sa force à faire une requête pour obtenir la liste des catégories puis une requête pour chaque catégorie pour obtenir la liste des forums de celle-ci.

Donc une personne désireuse de juste afficher la liste de tous les forums devrai déjà faire quelques requêtes, alors que d'après moi faire une requête du style api/forums, devrai renvoyé un objet du style

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
{
  'Savoirs': [
    {
      'pk': 1,
      'name': 'Programmation', 
      ...
    },
    ...
  ], 
  ...
}

De la même manière je supprimerai au minima toute notion de catégorie dans les urls, sauf dans le cas où un utilisateur souhaiterai obtenir qu'uniquement la liste des forum pour une catégorie donnée et encore… en obtenant la liste de tous les forums comme je viens de l'expliqué le client peu très aisément appliqué un filtre à ce niveau tout seul.

Concernant tes remarques:

  1. Pour moi la liste des sujets et messages ainsi que des sujets lié à un tags sont plus relatif à un moteur de recherche… je crois que sa devrai plus faire partie d'une ZEP à ce sujet (je pense ici à la ZEP-15 Navigation à facettes à travers le site
  2. Je pense effectivement que c'est trop long, d'où ma remarque sur la suppression d'un niveau à la base ^^ Cependant je pense aussi que comme le fait le forum actuellement, avoir une url juste de type forums/sujets/50 peut suffire…
  3. Pas compris la question :euh:

Je plussoie la suggestion de Fulbert concernant la suggestion des liens entre les messages ;)

+0 -0

Les requêtes GET ne lèvent pas d'erreurs 404 ?
C'est moi où l'on n'a pas accès au dernier message lu par l'utilisateur pour chaque sujet ?

+1 -0

Nombreuses remarques, dans l'ordre de lecture.

Simple question orthographique, tu mets le type long sans majuscule initiale, alors que tu en mets une à tous les autres types.

position | Interger | Position du message

  1. Y'a un -r- de trop à Integer.
  2. Pour les forums, tu as mis position_in_category, donc ce n'est pas cohérent. Je suggère de mettre position partout, étant évident que c'est la position dans l'entité de niveau supérieur.
  3. Quelle est l'utilité d'un champ position pour les messages, sachant que l’ordonnancement est entièrement déterminé par la date de publication des messages ?

Je ne suis pas satisfait par ta façon de gérer les like et dislike.

  1. Je n'arrive pas, intuitivement, à voir par quelle URL je devrais passer pour mettre un +1 ou un -1 à un message.
  2. Dans la représentation des messages, cette information prend la forme d'un simple décompte. Or, dans le fonctionnement actuel, c'est plus compliqué que ça : le forum sait qui a voté quoi, de manière à ce qu'on puisse changer son vote. En outre, il est prévu à terme de pouvoir afficher la liste des votants. Donc, tout ça pris en compte, il me paraît indispensable que cette liste soit fournie par l'API. Ça permettrait également d'ajouter une fonctionnalité permettant de savoir si on a déjà voté ou non, comme cela a aussi été demandé.

J'aimerais attirer votre attention sur quelques URLs particulières, à savoir la liste des sujets et des messages d'un membre et la liste des sujets d'un tag. Qu'est-ce que vous en pensez ?

Sur le papier, c'est une bonne idée. Dans la pratique, comme signalé plus haut, je crains que ça n'entre en interférence avec la mise en place de la ZEP-15.

Je sais que l'approche REST consiste à spécifier le chemin de la ressource dans l'URL mais je les trouve longues pour les sujets, encore plus pour les messages. Sachant en plus que, techniquement les identifiants sont séquentiels à travers les forums. Je ne sais donc pas si c'est très pertinent de spécifier un chemin qui ne sert à rien en fait. Est-ce que la question vous semble légitime ? Si oui, qu'est-ce que vous proposeriez ? L'approche REST est-elle stricte sur ce point ?

Je les trouve trop longs aussi. En outre, un sujet (et donc un message) est assez facilement susceptible de changer de forum voire de catégorie. Par conséquent, si ces informations apparaissent dans l'URL, ça veut dire qu'il faudra ajouter des redirections 301 à chaque fois qu'on déplace un sujet.

Même si cela ne pourrait être utilisé que par les staffs, je pense qu'il faudrait ajouter la possibilité de Créer, Modifier, Déplacer et Supprimer des forums et catégories. Histoire d'être complets.

Dans « Créer un sujet », la liste des paramètres est « title, subtitle, author, text (premier message) ». Pourquoi author ? En principe, l'auteur est identifié par son authentification, donc pourquoi laisser la possibilité à quelqu'un de créer un message au nom de quelqu'un d'autre, et donc créer la nécessité d'une vérification du back que l'on ne poste que sous son propre nom ? D'autant que pour l'ajout d'un message à un sujet, tu ne demandes pas cette information.

Afficher les informations d'un sujet

Renvoie les informations concernant un sujet donné. Le sujet est alors considéré comme lu par le système pour l'utilisateur qui fait la requête.

C'est une mauvaise idée. Cette étape correspond au moment où, sur le front actuel, on affiche la liste des sujets avec toutes leurs informations. Cela intervient donc avant le moment où on clique sur un sujet donné pour l'afficher. La mise en « lu » devrait intervenir plutôt à l'étape « Liste les messages » voire « Afficher les informations d'un message », selon comment est gérée l'information du dernier message non-lu.

+1 -0

Bon j'ai peur de te féliciter pour le boulot achevé, tu vas finir par te lasser :D

Je suis aussi partisan du "c'est trop long" pour les URL imposant la categorie et le forum parent, et ce pour toute les raisons proposee plus haut (notamment l'histoire de la redirection qui me semble importante)

@Fulbert, je ne pense pas que cette histoire de "sujet relatif" soit pertinent. L'API doit servir les ressources, pas les analyses. C'est le boulot de ton client de faire le traitement de la donnée.

+0 -0

Je dirais que bien que ce ne soit pas l'approche tout à fait dans la logique REST, il faudrait une redirection sur les URL longues vers les URL courtes. (des redirections permanentes). Pas du tout obligatoire, mais sait-on jamais ? Si c'est simple, pourquoi s'en priver.

Ensuite :

/api/forums/topics/:topicId me semble être le mieux adapté. C'est plus court.

D'ailleurs je préfixerais tout par forum

/api/forums/categories renverrait la liste des catégories.

/api/forums/categories/:categorieId renverrait des infos sur ladite catégorie (descriptions, nombre de topics, …).

/api/forums/categories/:categorieId/topics la liste des topics pour cette catégorie

Mais c'est vrai que du coup ça paraît inconsistant dès qu'on passe sur du :

/api/1/forums/:topicId/messages on l'on vire un niveau de hiérarchie. Mais à l'utilisation c'est plus pratique.

Qui plus est on voit un "clash" de noms entre :

  • /api/1/forums/:topicId
  • /api/1/forums/:categorieId

Difficile quand l'utilisateur exécute cette requête de savoir s'il demande une catégorie ou un topic en particulier…

J'ai du mal à trouver une solution élégante pour le moment… A part préfixer comme je l'ai fait plus haut :

  • /api/1/forums/topics/:topicId
  • /api/1/forums/categories/:categorieId

Si tu devais utiliser des URLs courtes (ce qui semble mieux, carrément), qu'est-ce-que tu proposerais dans ce genre de cas Andr0 ?

+1 -0

Pour ce qui est du problème des urls longues. J'aurai tendance à considérer un forum comme étant une sous-catégorie. ça implique que tu as des urls courtes du genre :

/api/:level/:id_level/, avec :level qui peut correspondre à "catégorie" ou à "forum", ou a n'importe quel autre niveau si un jour on décide d'organiser le forum sur 3 niveaux. ça te permet d'obtenir la liste des sujets d'un forum et/ou la liste des sujets d'une catégorie avec le même pattern d'url et on résous ainsi le problème des urls longues.

Ca en fait des réponses ! :) Alors je vais essayé de ne rien oublier :

@Fulbert

Je viens de voir ça, du coup je donne mon avis : c'est trop long. En plus ça oblige à connaître certains paramètres que l'on ne possède pas forcément à priori. Ex. : imaginons que l'API notif pointe vers un nouveau message du forum, il est probable qu'elle ne fournira que l'id de ce dit message (scénario purement fictif, elle pourrait très bien tout fournir).

En fait, si. Les notifications actuelles (et le nouveau système à venir) connaissent tout l'objet sur le sujet.

Ne serait-il pas possible d'implémenter une méthode qui permette de déterminer les liens entre des messages ? Il doit être possible de détecter les liens qui pointent vers un autre message du forum et d'enregistrer ces messages dans un champs (ou plutôt une autre table mais qu'importe) puis de les rendre avec l'API.

Je vais en parler plus loin.

@La source

J'ai une remarque à propos des catégories… est-ce réellement utile ?

Je pars d'un principe simple : Je ne sais pas ce que voudrons faire les applications tierces. Potentiellement, ils auront besoin de connaitre simplement les catégories, pourquoi pas ? Donc oui, je les propose dans l'API. Reste plus qu'à déterminer la manière.

Donc une personne désireuse de juste afficher la liste de tous les forums devrai déjà faire quelques requêtes, alors que d'après moi faire une requête du style api/forums, devrai renvoyé un objet du style

Dans la première révision de la spec que je propose, c'est possible. Tu peux récupérer tous les forums d'une catégorie. La seule restriction (que j'aimerais retirer), c'est de connaitre l'identifiant de la catégorie parente.

Pour moi la liste des sujets et messages ainsi que des sujets lié à un tags sont plus relatif à un moteur de recherche… je crois que sa devrai plus faire partie d'une ZEP à ce sujet (je pense ici à la ZEP-15 Navigation à facettes à travers le site

Je ne suis pas d'accord pour 2 raisons :

  • La ZEP-15 n'inclut aucune information, ni aucune spec relative à l'API.
  • Aujourd'hui, les tags ne sont pas partagés à travers tous les types de contenu. Les tags des forums sont uniquement destinés aux forums.

Par contre, je me suis aussi posé la question de savoir s'il fallait inclure les tags dans cette ZEP. Je suis ouvert s'il y a de meilleurs arguments.

@btw03

Les requêtes GET ne lèvent pas d'erreurs 404 ?

Si, effectivement. Si tu pointes vers un identifiant qui n'existe pas de la ressource souhaitée. Je vais rajouter ça dans la prochaine révision.

C'est moi où l'on n'a pas accès au dernier message lu par l'utilisateur pour chaque sujet ?

Tu soulèves un problème technique. Aujourd'hui, un modèle est entièrement dédié à ça pour connaitre cette information. D'ailleurs, cette information est en cours de refactoring avec la ZEP-24 qui prévoit le développement de son API avec.

@Dominus Carnufex

Simple question orthographique, tu mets le type long sans majuscule initiale, alors que tu en mets une à tous les autres types.

Limite, c'est pas important mais ça sera modifié dans la prochaine révision.

Pour les forums, tu as mis position_in_category, donc ce n'est pas cohérent. Je suggère de mettre position partout, étant évident que c'est la position dans l'entité de niveau supérieur.

Les champs renseignés et renvoyés par l'API correspondent au nom des attributs du modèle. Il est possible d'en changer le nom mais tu perds tout le côté générique. C'est quelque chose que je ne changerais donc pas pour le moment.

Quelle est l'utilité d'un champ position pour les messages, sachant que l’ordonnancement est entièrement déterminé par la date de publication des messages ?

Justement, non. Partout, c'est la position qui détermine l'ordre. Raison pour laquelle cette information est dans le modèle sur lequel se base l'API.

Je ne suis pas satisfait par ta façon de gérer les like et dislike.

Techniquement, c'est un compteur dans les modèles. L'API n'invente absolument rien, elle ne fait que se baser sur l'existant. ;)

Je n'arrive pas, intuitivement, à voir par quelle URL je devrais passer pour mettre un +1 ou un -1 à un message.

Modification d'un message, donc la méthode PUT.

Même si cela ne pourrait être utilisé que par les staffs, je pense qu'il faudrait ajouter la possibilité de Créer, Modifier, Déplacer et Supprimer des forums et catégories. Histoire d'être complets.

Ceci n'est pas possible sur le site pour l'instant. Ce sont les 2-3 administrateurs qui doivent les ajouter à la main par l'interface administrateur. L'idée d'une API n'est pas d'inventer des choses mais de proposer une API sur l'existant.

Dans « Créer un sujet », la liste des paramètres est « title, subtitle, author, text (premier message) ». Pourquoi author ?

Effectivement, c'est une erreur. Ca sera corrigé dans la prochaine révision.

C'est une mauvaise idée. Cette étape correspond au moment où, sur le front actuel, on affiche la liste des sujets avec toutes leurs informations.

Effectivement, je dois changer par l'API qui liste les messages d'un sujet.

@Hugo

J'ai pas vu la notion de signaler un message.

C'est volontaire. Il est possible que ça se refactor aussi par la ZEP-24 quand nous réfléchirons à la possibilité de pinger des utilisateurs.

Certains forum et catégories sont réservés à des groupes. Les admins et valido ont ainsi un forum particulier.

Tout à fait. Il ne sera affiché que les forums auxquels tu auras droit mais c'est un peu difficile de le faire ressortir dans une spec donc j'ai omis cette information.

@Javier et @firm1

C'est avec vos messages qui propose de nouvelles URLs que je vais proposer ma solution :

En fait, pendant le développement de la ZEP-23 sur l'API des MPs, j'ai été posé une question sur la mailing list de DRF (qui est la bibliothèque Django pour développer l'API). Je demandais à travers mon message, la bonne pratique pour spécifier plusieurs identifiants dans URL (en illustrant par un exemple, afficher les informations d'un message dans un MP).

Voici la réponse que j'ai obtenue :

I did not fully understand your question, but IN MOST cases there's no need to have two pks in a url. The REST archtectural style forsees the use o hypermedia (links) for navigation. This means that [normaly] there's no need to build ceprehensible urls because the agent using the api should be following links provided in api responses. In a more practical way: unless you have a real good reason, dont complicate your code by requiring 2 pks in the url. Simpli use one and verify user permissions against the refered object. Keep it simple.

J'avoue avoir été un peu étonné et je me suis donc un peu renseigné. Après une rapide recherche, DRF propose une vue HyperLink des résultats qu'il renvoie à l'utilisateur. On se balade alors de lien en lien.

Je ne suis pas encore du tout expert dans ce domaine. Cette approche REST m'est totalement étrangère pour le moment mais je pense que ça peut être le nouveau challenge de cette ZEP API. Qu'est ce que vous en pensez ?

@Andr0 : Je n'ai pas tout compris aussi mais pourquoi pas ! Par contre, je pense qu'il faut quand même tout faire commencer par /api/forums/ pour que l'on sache bien que c'est le module des forums.

+1 -0

Salut ici,

ZdS me signale que ça fait plus de 90 jours qu'il n'y a pas eu de l'activité ici et ça ne va pas du tout ça ! D'ici le moment où je me remettrais au développement de ZdS, j'aimerais au moins finir les specs de cette ZEP pour pouvoir directement attaqué sur le développement.

D'après ce que je comprends en parcourant rapidement la discussion, le plus gros problème repose sur la longueur des URLs, le reste ressemblant fortement à la ZEP des MPs et donc n'a pas vraiment besoin d'un débat.

J'aimerais donc vous soumettre une nouvelle série d'URL où je fais plusieurs choix :

  • Les catégories est une information plus que secondaire. Autant, on identifie un sujet à son forum et encore plus un message à son sujet, mais on identifie beaucoup moins un forum à sa catégorie. Les catégories sont donc écartées des URLs après les URLs spécifiques à cette ressource mais il sera toujours possible de filtrer les forums par catégorie via un paramètre dans son URL.
  • Le reste a été inspiré de l'API REST de GitHub, plus précisément des "repos", "issues" et "comments" que je fais correspondre aux "forums", "sujets" et "messages". Cela m'a semblé un bon point de départ à ma réflexion. Vous pouvez trouver la documentation des issues GitHub via ce lien.

Maintenant, donnez moi votre avis sur ce tableau :

Méthode Fonctionnalité URL
Catégories
GET Liste toutes les catégories /api/categories
POST Crée une catégorie** /api/categories
GET Récupère une catégorie /api/categories/:id
PUT Edite une catégorie** /api/categories/:id
Forums
GET Liste tous les forums /api/forums/
POST Crée un forum** /api/forums/
GET Récupère un forum /api/forums/:id
PUT Edite un forum** /api/forums/:id
Sujets
GET Liste tous les sujets d’un forum /api/forums/:forum/sujets
GET Liste tous les sujets du membre authentifié* /api/membres/sujets
GET Liste tous les sujets d'un membre /api/membres/:membre/sujets
GET Liste tous les sujets d'un tag /api/tags/:tag/sujets
POST Crée un sujet* /api/forums/:forum/sujets
GET Récupère un sujet /api/forums/:forum/sujets/:sujet
PUT Edite un sujet* /api/forums/:forum/sujets/:sujet
Tags
GET Liste tous les tags /api/forums/tags
GET Récupère un tag /api/forums/tags/:tag
Messages
GET Liste les messages d'un sujet /api/forums/:forum/sujets/:sujet/messages
GET Liste les messages d'un membre authentifié* /api/membres/messages
GET Liste les messages d'un membre /api/membres/:membre/messages
POST Crée un message dans un sujet* /api/forums/:forum/sujets/:sujet/messages
GET Récupère un message /api/forums/:forum/sujets/:sujet/messages/:message
PUT Edite un message* /api/forums/:forum/sujets/:sujet/messages/:message

* : Il faut être authentifié

** : Il faut appartenir au staff

+2 -0

Pourquoi faut-il faire partie du staff pour poster un message ainsi que l'édition si on en est l'auteur ?

Sinon faudrait penser au +1 et -1 ainsi que au "Cette réponse m'a aidée"

Ps: J'ai pas tout relu, juste la dernière réponse donc si sa tombe c'est déjà écris plus haut, aussi si tel est le cas je m'en excuse.

+1 -0

Andr0 souhaitait que je donne mon avis, donc c'est parti :^)

Je m'excuse d'avance pour la non-organisation/le bordel dans ce message

Les endpoints

Y'en quelques uns qui me gênent sémantiquement, c'est tous ceux relatifs à l'utilisateur en cours.

En effet, pour moi, /membres est la resource qui correspond à l'ensemble des utilisateurs. Donc logiquement, /membres/sujets correspondrait à tous les sujets de tous les utilisateurs. Or, ce n'est pas le cas dans cette spec. Pour moi, si on veut un raccourci à /membres/[mon pseudo]/..., ça serait /membres/me/... (ou self, ou un autre truc dans le genre ; j'aime bien me perso). Du coup, /membres/me/sujets désignerait les sujets d'un élément de /membres, de l'utilisateur connecté. L'autre solution (qui pourrait même être mieux je trouve), est d'avoir /membre, au singulier, qui désigne l'utilisateur courant. Ca évite aussi d'avoir des conflits si jamais on a un membre qui décide de s'appeler me :-° (note: si on change ici, il faudra uniformiser ce changement sur les autres APIs qui utilisent cet endpoint)

Un autre endpoint qui serait selon moi utile, sur une ressource /messages/[id], une sous-ressource /messages/[ids...]/karma en GET + POST/PUT (enfin, karma, like ou autre, à voir), pour les likes d'un message. Pourquoi, d'abord pour avoir un endpoint pour facilement "liker". A noter qu'il pourrait y avoir plusieurs IDs sur un GET (pas sur le POST ; séparés d'une virgule), pour permettre de mettre à jour les likes en direct sur la page. Vous aurez remarqué que la je pense surtout aux aspects de l'API qui risquent de vraiment servir au site à court terme :)

Les réponses

Alors, d'abord pour moi il manque une information importante sur la plupart des ressource, c'est un flag can_edit, qui serait à true si le membre authentifié peut éditer le message/thread/forum/catégorie demandé. Ca dépend donc de si l'utilisateur est staff ou non, et si c'est l'owner du post en question ou non. Même si c'est une information qui peut être "devinée" implicitement, je préférerais que ça soit indiqué explicitement.

Ensuite, sur les infos qu'on a déjà, mais qui devraient être indiquées autrement:

Je préférerais un objet text: { markdown: ..., html: ... } plutôt que text: ..., text_html: ..., avec éventuellement les données contextuelles la dedans (posts relatifs (les trucs cités), utilisateurs mentionnés, liste des liens/images…). Pourquoi la dedans ? Parce que cette ressource pourrait être générique, et utilisée à d'autres endroits (MP, tutos…), et que ça peut éviter d'avoir du code dupliqué. En plus, ça peut être une sous-ressource, en GET + PUT (genre /messages/[id]/text) pour non seulement éditer (parce qu'est-ce qu'on veut bien vouloir éditer à part le message lui-même ?), mais aussi récupérer les sous-ressources facilement (les utilisateurs mentionnés, les autres posts…).

Du coup (vous aurez remarqué que j'écris ce message au fur et à mesure que les idées viennent), on devrait avoir une ressource /text, ou /utils/text ou whatever uniquement en POST (enfin, je sais pas si c'est le plus approprié, mais la dans le train, j'ai pas accès à la définition de chacune des actions HTTP :o) ) qui permettrait de process un markdown donné, pour non seulement en faire le rendu, mais aussi pour en extraire les informations contextuelles. Mais bon, je pense que la je suis hors-scope, et que pourrait faire l'objet d'une ZEP à part. En tout cas, à noter quelque part, parce que ça pourrait servir à l'éditeur dans un futur plus ou moins lointain (càd quand j'aurais trouvé le temps et le courage de toucher ce machin, càd pas tout de suite :^) )

Je m'égare, j'avais encore un truc que j'ai mentionné hier soir sur IRC, il faudrait que la sous-ressource karma (ou like) mentionnée plus haut soit sous forme de sous objet du type kamra: { likes: 42, dislikes: 12, status: "liked" }. D'abord, c'est plus clair (enfin, je trouve), et ça ajoute une info qu'on avait pas dans la spec actuelle, càd si l'utilisateur actuel a like ou non le message en question. Du coup, j'ai un autre argument de "pourquoi ça doit être un endpoint à part" (j'vous ai déjà dit que j'écris ce message au fur et à mesure ?), c'est que si on désanonymise les likes (j'ai plus le sujet sous la main), il faudrait pouvoir récupérer la liste des gens qui ont like, et comme ça demande des join dans tous les sens, et des requêtes à gogo, je pense que c'est une information qui ne sera pas affichée au chargement de la page, mais demandée en AJAX au survol, quand l'utilisateur le demande. Je sais pas si cette partie est très claire, mais je pense que c'est important. Je prendrais le temps de répondre et expliquer en détail ce soir si c'est pas clair, pas le temps maintenant :^)


Bon, ça sera tout pour ce message, je m'excuse vraiment pour le bordel de celui-ci, je l'ai vraiment écris à l'arrache dans le train avant d'aller en cours, y'a sûrement des tonnes de trucs pas clairs, mais j'ai préféré l'envoyer maintenant plutôt que d'attendre ce soir pour le réorganiser et le réécrire correctement.

Sandhose

+4 -0

Sinon faudrait penser au +1 et -1 ainsi que au "Cette réponse m'a aidée"

La source

Et "Signaler ce message".

+1 avec Sandhose pour un endpoint différent de /api/membres pour le membre actuellement connecté.

Pareil pour les like/karma, un endpoint séparé est plus simple à utiliser. Et surtout, ça permet de faire une requête en disant juste "like" ou "dislike" plutôt que de bricoler un truc à base de "j'incrémente la valeur de "like"/"dislike".

+0 -0

@sandhose

Les endpoints

L'autre solution (qui pourrait même être mieux je trouve), est d'avoir /membre, au singulier, qui désigne l'utilisateur courant. Ca évite aussi d'avoir des conflits si jamais on a un membre qui décide de s'appeler me :-° (note: si on change ici, il faudra uniformiser ce changement sur les autres APIs qui utilisent cet endpoint)

J'aime beaucoup cette solution. Je vais changer les URLs avec cette solution.

Un autre endpoint qui serait selon moi utile, sur une ressource /messages/[id], une sous-ressource /messages/[ids...]/karma en GET + POST/PUT (enfin, karma, like ou autre, à voir), pour les likes d'un message. Pourquoi, d'abord pour avoir un endpoint pour facilement "liker". A noter qu'il pourrait y avoir plusieurs IDs sur un GET (pas sur le POST ; séparés d'une virgule), pour permettre de mettre à jour les likes en direct sur la page. Vous aurez remarqué que la je pense surtout aux aspects de l'API qui risquent de vraiment servir au site à court terme :)

Alors, tout en sachant que le like est possible avec l'édition d'un message, je comprends le besoin que tu as de rajouter un endpoint pour liker un message. Fonctionnellement parlant, le like d'un message ne semble pas directement lié à l'édition de ce dernier et donc, mérite le endpoint dédié.

Par contre :

  • Pourquoi permettre d'y accéder en GET ? J'y vois beaucoup moins d'intérêt mais tu arriveras peut-être à me convaincre.
  • Partons-nous sur du POST ou du PUT ? Personnellement, malgré le fait que nous sommes sur du PUT pour l'édition d'un message, je partirais sur du POST pour le like. Avec le endpoint, on dissocie ce rattachement à l'édition technique du message. On a alors plutôt l'impression de créer une information (POST) que d'en éditer une (PUT).
  • Autant je suis pour le endpoint du like, autant je le suis beaucoup moins sur le multiple like et pour tout un tas de raison : l'url est vraiment moche, les abus sont faciles, il faut donc penser aux limites, etc. C'est beaucoup moins naturel que le endpoint sur une seule ressource.
Les réponses

Alors, d'abord pour moi il manque une information importante sur la plupart des ressource, c'est un flag can_edit, qui serait à true si le membre authentifié peut éditer le message/thread/forum/catégorie demandé. Ca dépend donc de si l'utilisateur est staff ou non, et si c'est l'owner du post en question ou non. Même si c'est une information qui peut être "devinée" implicitement, je préférerais que ça soit indiqué explicitement.

Alors là je ne peux pas être d'accord. Les codes erreurs HTTPs servent justement à ça (code 403 pour être précis). Tu veux polluer les résultats de l'API par de l'information qui est déjà donné sous une forme standardisée. Je suis désolé mais là je suis catégorique.

Je préférerais un objet text: { markdown: ..., html: ... } plutôt que text: ..., text_html: ..., avec éventuellement les données contextuelles la dedans (posts relatifs (les trucs cités), utilisateurs mentionnés, liste des liens/images…). Pourquoi la dedans ? Parce que cette ressource pourrait être générique, et utilisée à d'autres endroits (MP, tutos…), et que ça peut éviter d'avoir du code dupliqué.

Nous discutons ici de la spec de l'API, ce n'est donc pas le lieux pour parler de la technique. mais si tu veux vraiment en parler, sache qu'il n'y aura pas de duplication de code peu importe la solution.

Je suis mitigé pour cette proposition. A l'époque où nous réfléchissions de la spec de l'API des MPs, nous avions fais un choix qui était d'afficher par défaut le texte du markdown et le HTML à la demande (où l'inverse, ça remonte un peu). Je n'ai rien contre faire évoluer la spec tant que notre API est au stade de bêta. D'ailleurs, ta solution a plutôt du sens. Par contre, si nous permettons toujours de renseigner qu'un seul format au détriment des autres, ta proposition perd en intérêt.

En plus, ça peut être une sous-ressource, en GET + PUT (genre /messages/[id]/text) pour non seulement éditer (parce qu'est-ce qu'on veut bien vouloir éditer à part le message lui-même ?), mais aussi récupérer les sous-ressources facilement (les utilisateurs mentionnés, les autres posts…).

Attention de ne pas tomber dans le piège de se dire que tout à besoin d'un endpoint. Ici, fonctionnellement, le texte fait parti intégrante de la ressource du message et, selon moi, doit donc obligatoirement passer par la route d'édition d'un message.

Sur ce point, je ne suis pas pour. A ce compte là, pourquoi ne pas mettre un endpoint pour tous les attributs d'un message.

Du coup […], on devrait avoir une ressource /text, ou /utils/text ou whatever uniquement en POST […] qui permettrait de process un markdown donné, pour non seulement en faire le rendu, mais aussi pour en extraire les informations contextuelles. Mais bon, je pense que la je suis hors-scope […]

C'est quelque chose que j'aimerais faire depuis longtemps mais oui, c'est hors scope. L'API des forums me prendra déjà bien assez de temps. :)

Je m'égare, j'avais encore un truc que j'ai mentionné hier soir sur IRC, il faudrait que la sous-ressource karma (ou like) mentionnée plus haut soit sous forme de sous objet du type kamra: { likes: 42, dislikes: 12, status: "liked" }. […] si on désanonymise les likes (j'ai plus le sujet sous la main), il faudrait pouvoir récupérer la liste des gens qui ont like, et comme ça demande des join dans tous les sens, et des requêtes à gogo […]

J'aime l'idée du bloc karma sur un message mais est-ce que tu aurais un exemple pour afficher toutes les personnes qui ont liké et disliké le message ?

Et "Signaler ce message".

Effectivement, c'est une action qui pourrait faire l'objet d'un endpoint.

[…]

Alors, tout en sachant que le like est possible avec l'édition d'un message, je comprends le besoin que tu as de rajouter un endpoint pour liker un message. Fonctionnellement parlant, le like d'un message ne semble pas directement lié à l'édition de ce dernier et donc, mérite le endpoint dédié.

Par contre :

  • Pourquoi permettre d'y accéder en GET ? J'y vois beaucoup moins d'intérêt mais tu arriveras peut-être à me convaincre.
  • Partons-nous sur du POST ou du PUT ? Personnellement, malgré le fait que nous sommes sur du PUT pour l'édition d'un message, je partirais sur du POST pour le like. Avec le endpoint, on dissocie ce rattachement à l'édition technique du message. On a alors plutôt l'impression de créer une information (POST) que d'en éditer une (PUT).
  • Autant je suis pour le endpoint du like, autant je le suis beaucoup moins sur le multiple like et pour tout un tas de raison : l'url est vraiment moche, les abus sont faciles, il faut donc penser aux limites, etc. C'est beaucoup moins naturel que le endpoint sur une seule ressource.

Pour le GET et les IDs multiples, c'est juste dans l'idée de sur le site, pouvoir régulièrement mettre à jour tous les +1/-1, en un seul appel, et qui soit pas gourmand en ressource non plus. En gros, je suis sur un thread du forum, et les likes se mettent à jour tous seuls sans recharger la page. Après, ça pourrait passer par un GET sur les posts directement, mais c'est juste plus lourd. Pour le POST/PUT, honnêtement, ça m'est égal, parce que ça peut autant désigner "J'ajoute mon like" que "Je supprime/modifie mon like". Je pense que c'est pas grand chose de proposer les deux.

Les réponses

Alors, d'abord pour moi il manque une information importante sur la plupart des ressource, c'est un flag can_edit, qui serait à true si le membre authentifié peut éditer le message/thread/forum/catégorie demandé. Ca dépend donc de si l'utilisateur est staff ou non, et si c'est l'owner du post en question ou non. Même si c'est une information qui peut être "devinée" implicitement, je préférerais que ça soit indiqué explicitement.

Alors là je ne peux pas être d'accord. Les codes erreurs HTTPs servent justement à ça (code 403 pour être précis). Tu veux polluer les résultats de l'API par de l'information qui est déjà donné sous une forme standardisée. Je suis désolé mais là je suis catégorique.

Well, je suis pas tout à fait d'accord. Simplement que dans ta logique, soit on devine si l'utilisateur courant peut ou non modifier le post/topic/whatever (ce qui peut être tricky: suis-je staff ? suis-je banni ? le topic est-il lock ? dans un forum sur lequel j'ai les droits ? — Certes, j'exagère un peu, et pour le forum ça reste relativement trivial de déterminer ça ; mais sur d'autres resources, genre, les Unes, ça pourrait être plus embêtant à deviner), soit on teste en se disant "Ah bah je vais voir si je peux modifier ça… Ah bah apparement non". En gros, tu préviens ton utilisateur qu'en fait il a pas le droit de faire ça après qu'il ai déjà tout envoyé. C'est comme si on affichait le bouton "Editer" sur tous les posts, et que quand on essaie d'envoyer, il y ait une erreur "Vous n'avez pas le droit de faire ça".

[…] Je suis mitigé pour cette proposition. A l'époque où nous réfléchissions de la spec de l'API des MPs, nous avions fais un choix qui était d'afficher par défaut le texte du markdown et le HTML à la demande (où l'inverse, ça remonte un peu). Je n'ai rien contre faire évoluer la spec tant que notre API est au stade de bêta. D'ailleurs, ta solution a plutôt du sens. Par contre, si nous permettons toujours de renseigner qu'un seul format au détriment des autres, ta proposition perd en intérêt.

En soi, vu que le texte html+md sont sur la même table (en tout cas de mémoire c'est le cas), ça coûte rien de donner les deux, donc autant tout envoyer.

En plus, ça peut être une sous-ressource, en GET + PUT (genre /messages/[id]/text) pour non seulement éditer (parce qu'est-ce qu'on veut bien vouloir éditer à part le message lui-même ?), mais aussi récupérer les sous-ressources facilement (les utilisateurs mentionnés, les autres posts…).

Attention de ne pas tomber dans le piège de se dire que tout à besoin d'un endpoint. Ici, fonctionnellement, le texte fait parti intégrante de la ressource du message et, selon moi, doit donc obligatoirement passer par la route d'édition d'un message.

Sur ce point, je ne suis pas pour. A ce compte là, pourquoi ne pas mettre un endpoint pour tous les attributs d'un message.

Après réflexion, ouais, tu as raison. Juste dans ce cas ne pas donner par défaut les objets relatifs (question perfs), mais permettre de les renvoyer avec s'il le faut.

[…]

Je m'égare, j'avais encore un truc que j'ai mentionné hier soir sur IRC, il faudrait que la sous-ressource karma (ou like) mentionnée plus haut soit sous forme de sous objet du type kamra: { likes: 42, dislikes: 12, status: "liked" }. […] si on désanonymise les likes (j'ai plus le sujet sous la main), il faudrait pouvoir récupérer la liste des gens qui ont like, et comme ça demande des join dans tous les sens, et des requêtes à gogo […]

J'aime l'idée du bloc karma sur un message mais est-ce que tu aurais un exemple pour afficher toutes les personnes qui ont liké et disliké le message ?

J'y ai pensé sur le moment, mais pas eu le temps de formuler ça correctement. En fait, on pourrait même partir sur un truc du genre:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
"karma": {
  "likes": {
    "count": 42,
    "list": [ // ou `users`
      { ... }, // soit des objets complets, soit des listes d'ID
      { ... },
      ...
    ]
  },
  "dislikes": {
    "count": 12,
    "list": [
      { ... },
      { ... },
      ...
    ]
  }
}

L'avantage est qu'on est prêt pour la désanonymisation des +1/-1, l'inconvénient c'est qu'en attendant, ça fait du markup pour rien (on aurait pas le list ; pour moi c'est pas gênant pour autant)

+1 -0

Pour le GET et les IDs multiples, c'est juste dans l'idée de sur le site, pouvoir régulièrement mettre à jour tous les +1/-1, en un seul appel, et qui soit pas gourmand en ressource non plus. En gros, je suis sur un thread du forum, et les likes se mettent à jour tous seuls sans recharger la page.

Je comprends l'intérêt mais je ne trouve vraiment pas ça naturel comme URL. Pour une première version en tout cas, je serais d'avis d'écarter cette proposition.

Pour le POST/PUT, honnêtement, ça m'est égal, parce que ça peut autant désigner "J'ajoute mon like" que "Je supprime/modifie mon like". Je pense que c'est pas grand chose de proposer les deux.

Allons sur du POST pour le like et dislike et du DELETE pour le retirer !

Well, je suis pas tout à fait d'accord. Simplement que dans ta logique, soit on devine si l'utilisateur courant peut ou non modifier le post/topic/whatever (ce qui peut être tricky: suis-je staff ? suis-je banni ? le topic est-il lock ? dans un forum sur lequel j'ai les droits ?

Désolé mais je reste catégorique. Tu me décris précisément le mécanisme des permissions et ceci doit être géré par le code de réponse HTTP.

En soi, vu que le texte html+md sont sur la même table (en tout cas de mémoire c'est le cas), ça coûte rien de donner les deux, donc autant tout envoyer.

Tout à fait, ça m'a demandé de casser un peu le côté générique pour mettre en oeuvre ce choix mais c'est une demande de la communauté. Donc on ne va pas revenir dessus. :)

J'y ai pensé sur le moment, mais pas eu le temps de formuler ça correctement. En fait, on pourrait même partir sur un truc du genre:

Quand est-il pour les likes/dislikes anonymes ? On mentionne dans la réponse qu'ils sont anonymes ? On donne une liste vide ? Mais j'aime bien l'idée, faut juste se fixer sur une spec !

Désolé mais je reste catégorique. Tu me décris précisément le mécanisme des permissions et ceci doit être géré par le code de réponse HTTP.

Andr0

Je suis d'accord avec Sandhose, tu es en train de dire qu'il faut essayé pour savoir si on a le droit ? c'est un pur non sens !

Le code erreur http c'est si on s'y prend mal (qu'on a pas vérifier en amont si on avait ou non le droit) mais il faut fournir au développeur le moyen de le déterminer par avance (ne fusse que pour afficher/cacher le bouton d'action)

+0 -0

Donc, si je comprends bien, vous êtes en train de me dire que la bonne façon de faire serait de polluer (parce que c'est le mot quand une rajoute une information supplémentaire qui n'est pas lié à la ressource) le résultat que nous renvoyons par une information potentiellement intéressante et sur toutes les ressources pour savoir si l'utilisateur qui fait la requête peut ou non éditer cette ressource ?

Très bien, si vous me donnez des exemples d'API (reconnues comme de bonnes API) qui utilise cette pratique, je m'y plierais mais sincèrement, je trouve ça dégueulasse.

Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte