Projet

Général

Profil

Development #36377

API pour définir les membres (directs) d'un rôle

Ajouté par Frédéric Péters il y a plus de 4 ans. Mis à jour il y a plus de 4 ans.

Statut:
Fermé
Priorité:
Normal
Assigné à:
Catégorie:
-
Version cible:
-
Début:
24 septembre 2019
Echéance:
% réalisé:

0%

Temps estimé:
Patch proposed:
Oui
Planning:
Non

Description

On a une API permettant d'ajouter(/retirer) un utilisateur à un rôle, roles/(?P<role_uuid>[\w+]*)/members/(?P<member_uuid>[^/]+)/.

On pourrait avoir une API roles/(?P<role_uuid>[\w+]*)/members/, où un POST d'une liste de <member_uuid> ajouterait tout ceux-ci, un DELETE retirerait tout ceux-ci, mais surtout, un PUT viderait/définirait la liste des membres ?


Fichiers

0001-api-direct-role-members-definition-36377.patch (12,2 ko) 0001-api-direct-role-members-definition-36377.patch Paul Marillonnet, 26 septembre 2019 16:33
0001-api-direct-role-members-definition-36377.patch (12,4 ko) 0001-api-direct-role-members-definition-36377.patch Paul Marillonnet, 26 septembre 2019 17:36
0001-api-do-not-give-uuid-validity-info-to-unauthorized-r.patch (2,23 ko) 0001-api-do-not-give-uuid-validity-info-to-unauthorized-r.patch Paul Marillonnet, 27 septembre 2019 11:25
0002-api-explicit-role-membership-addition-removal-testin.patch (1,21 ko) 0002-api-explicit-role-membership-addition-removal-testin.patch Paul Marillonnet, 27 septembre 2019 11:25
0003-api-role-members-direct-definition-36377.patch (10,4 ko) 0003-api-role-members-direct-definition-36377.patch Paul Marillonnet, 27 septembre 2019 11:25
0001-api-role-members-direct-definition-36377.patch (10,3 ko) 0001-api-role-members-direct-definition-36377.patch Paul Marillonnet, 02 octobre 2019 16:15
0001-api-role-members-direct-definition-36377.patch (9,91 ko) 0001-api-role-members-direct-definition-36377.patch Paul Marillonnet, 03 octobre 2019 13:53
0001-api-role-members-direct-definition-36377.patch (10,3 ko) 0001-api-role-members-direct-definition-36377.patch Paul Marillonnet, 04 octobre 2019 10:15
0001-api-role-members-direct-definition-36377.patch (10,6 ko) 0001-api-role-members-direct-definition-36377.patch Paul Marillonnet, 04 octobre 2019 10:21
0001-api-role-members-direct-definition-36377.patch (11,3 ko) 0001-api-role-members-direct-definition-36377.patch Paul Marillonnet, 04 octobre 2019 11:40

Révisions associées

Révision 1cedef29 (diff)
Ajouté par Paul Marillonnet il y a plus de 4 ans

api: role members direct definition (#36377)

Historique

#1

Mis à jour par Benjamin Dauvergne il y a plus de 4 ans

Ça m'irait qu'on rapproche l'API du fonctionnement de JSONAPI

# ajouter l'utilisateur 1234
POST /api/roles/xyz/relationships/members/

{
   "data": [
     {"uuid": "1234"}
   ]
}
# écraser la liste des membres avec les utilisateurs pointés
PATCH /api/roles/xyz/relationships/members/

{
   "data": [
     {"uuid": "1234"}
   ]
}

# retirer l'utilisateur 1234
DELETE /api/roles/xyz/relationships/members/

{
   "data": [
     {"uuid": "1234"}
   ]
}

L'idée étant que /api/roles/xyz/members/ fonctionne par contre comme /api/users/ un jour (et faut prendre en compte le cas {"sub": "1234"} pour les services OIDCs.

L'ancienne API serait déprécié progressivement.

#2

Mis à jour par Benjamin Dauvergne il y a plus de 4 ans

  • Assigné à mis à Nicolas Roche
#3

Mis à jour par Paul Marillonnet il y a plus de 4 ans

  • Assigné à changé de Nicolas Roche à Paul Marillonnet

Je vais prendre celui-là.

#4

Mis à jour par Paul Marillonnet il y a plus de 4 ans

Que fait-on lorsqu'un des uuid dans le payload n'existe pas pour a2 ?
J'imagine que le comportement actuel de RoleMembershipsAPI, qui consiste à renvoyer un HTTP 404, n'est plus valable.
Au contraire, on pourrait renvoyer la liste des UUID d'usagers qui ont été affectés par l'appel.

#5

Mis à jour par Frédéric Péters il y a plus de 4 ans

Retourner le nouveau contenu, genre ce que pourrait retourner GET /api/roles/xyz/relationships/members/ qui n'était pas mentionné, ça me semble raisonnable.

#6

Mis à jour par Benjamin Dauvergne il y a plus de 4 ans

Paul Marillonnet a écrit :

Que fait-on lorsqu'un des uuid dans le payload n'existe pas pour a2 ?

Je serai pour renvoyer une erreur 400 par défaut, si c'est gênant on inventer un paramètre pour débrayer ; un truc permissif n'obligera pas les gens à valider le retour.

J'imagine que le comportement actuel de RoleMembershipsAPI, qui consiste à renvoyer un HTTP 404, n'est plus valable.

Non et c'était moche.

Au contraire, on pourrait renvoyer la liste des UUID d'usagers qui ont été affectés par l'appel.

Si tout se passe bien normalement ce serait 204 No content.

#7

Mis à jour par Paul Marillonnet il y a plus de 4 ans

Une première version, qui reprend ce qui est fait pour l'API /roles/<role_uuid>/members/<member_uuid>/, en ajoutant du code dans la classe associée.
Elle reprend en particulier l'idée de renvoyer un 20{0,1} quand ça se passe bien, avec une courte phrase de confirmation de l'opération effectuée.

#8

Mis à jour par Benjamin Dauvergne il y a plus de 4 ans

Paul Marillonnet a écrit :

Une première version, qui reprend ce qui est fait pour l'API /roles/<role_uuid>/members/<member_uuid>/, en ajoutant du code dans la classe associée.
Elle reprend en particulier l'idée de renvoyer un 20{0,1} quand ça se passe bien, avec une courte phrase de confirmation de l'opération effectuée.

Je préférerai une classe séparée pour pouvoir déprécier l'autre à un moment et pour l'URL /api/roles/<role_uuid>/relationships/members/.

#9

Mis à jour par Paul Marillonnet il y a plus de 4 ans

  • Statut changé de Solution proposée à En cours

Benjamin Dauvergne a écrit :

Je préférerai une classe séparée pour pouvoir déprécier l'autre à un moment et pour l'URL /api/roles/<role_uuid>/relationships/members/.

Oui, ce sera plus propre comme ça.

#10

Mis à jour par Paul Marillonnet il y a plus de 4 ans

Voilà, c'est mieux comme ça, en effet.

#12

Mis à jour par Frédéric Péters il y a plus de 4 ans

Je ne sais pas ce qu'authentic ou DRF font côté transactions, et du coup je suggérerais des explicites .atomic(). (mais me répondre que c'est bon c'est géré en amont ça me va très bien).

#13

Mis à jour par Lauréline Guérin il y a plus de 4 ans

    def patch(self, request, *args, **kwargs):
        self.role.members.all().delete()
        for member in self.members:
            self.role.members.add(member)

et pourquoi pas juste

    def patch(self, request, *args, **kwargs):
        self.role.members.set(members)

?

#14

Mis à jour par Paul Marillonnet il y a plus de 4 ans

Lauréline Guerin a écrit :

et pourquoi pas juste

Bien vu, merci.

De façon similaire, usage des fonctions d'ajout et de retrait du ManyRelatedManager de l'ORM de django. Les questions d'atomicité dans la vue de l'API ne se posent donc plus.

#15

Mis à jour par Paul Marillonnet il y a plus de 4 ans

(tests en django 1.8 qui cassent mais qui cependant n'ont plus lieu d'être, je viens de pousser une branche rebasée sur un master à jour)

#16

Mis à jour par Benjamin Dauvergne il y a plus de 4 ans

C'est PATCH -> add et PUT/POST -> set.

#17

Mis à jour par Paul Marillonnet il y a plus de 4 ans

Discussion sur le salon tech à ce sujet, il s'agit d'une collection donc c'est bien POST -> add et PATCH/PUT -> set.

Nouveau patch avec :
  • ajout de /relationships/ dans le motif d'uri
  • test de l'absence de doublon
  • retrait de la fixture paramétrée simple_user qui provoquait inutilement une explosion combinatoire (les tests écrits dans ce patch étaient déclinés en 96 appels différents...)
#18

Mis à jour par Benjamin Dauvergne il y a plus de 4 ans

Je ne suis pas d'accord avec le 404 quand on recherche les UUIDs, il faut renvoyer une 400 dans tous les cas, une ValidationError expliquant l'uuid qui foire.

#19

Mis à jour par Paul Marillonnet il y a plus de 4 ans

  • Statut changé de Solution proposée à En cours

Benjamin Dauvergne a écrit :

Je ne suis pas d'accord avec le 404 quand on recherche les UUIDs, il faut renvoyer une 400 dans tous les cas, une ValidationError expliquant l'uuid qui foire.

Ok ça me va. D'ailleurs c'est hors specs JSONAPI1.

1 https://jsonapi.org/format/#crud-updating-relationship-responses :

 200 OK
[…]

403 Forbidden
[…]

A server MAY respond with other HTTP status codes.
#20

Mis à jour par Paul Marillonnet il y a plus de 4 ans

#21

Mis à jour par Paul Marillonnet il y a plus de 4 ans

La même chose en prêtant attention à la longueur maximale des lignes dans le code de la vue.

#22

Mis à jour par Benjamin Dauvergne il y a plus de 4 ans

Paul Marillonnet a écrit :

Benjamin Dauvergne a écrit :

Je ne suis pas d'accord avec le 404 quand on recherche les UUIDs, il faut renvoyer une 400 dans tous les cas, une ValidationError expliquant l'uuid qui foire.

Sans aller jusqu'à relire le document JSONAPI (je veux pas en faire une bible, mais on a pas de référence sur comment structurer nos APIs pour l'instant à part renvoyer {'err':...} et donc on fait un peut chaque fois des choses différentes... bref) 404 c'est que la ressource n'existe pas, la ressource existe, par contre la requête est bien erronée, donc 400.

#23

Mis à jour par Benjamin Dauvergne il y a plus de 4 ans

Manque encore un check que request.data est bien un dict (tu te serais moins emmerdé avec un Serializer).

#24

Mis à jour par Paul Marillonnet il y a plus de 4 ans

Benjamin Dauvergne a écrit :

Manque encore un check que request.data est bien un dict (tu te serais moins emmerdé avec un Serializer).

Voilà.

#25

Mis à jour par Benjamin Dauvergne il y a plus de 4 ans

  • Statut changé de Solution proposée à Solution validée
#26

Mis à jour par Paul Marillonnet il y a plus de 4 ans

  • Statut changé de Solution validée à Résolu (à déployer)
commit 1cedef29c9d4973061b7731626e390c985770bb8
Author: Paul Marillonnet <pmarillonnet@entrouvert.com>
Date:   Fri Sep 27 11:24:13 2019 +0200

    api: role members direct definition (#36377)
#27

Mis à jour par Frédéric Péters il y a plus de 4 ans

  • Statut changé de Résolu (à déployer) à Solution déployée

Formats disponibles : Atom PDF