API - Plusieurs demandes vs la séparation des rôles d'utilisateur
-
22-12-2019 - |
Question
Je suis en train de travailler sur le frontend d'une seule page de l'application et je liste un certain nombre d'étudiants.Chaque étudiant est attaché à une certaine user_id
C'est ce que l'API retourne pour tous les rôles d'utilisateur (superadmin, administrateur, professeur, élève) quand j'ai effectuer GET /students
:
{
address: null
class_id: 184
class_name: "I B"
date_of_birth: null
first_name: "first"
gender: null
grade: 1
id: 192
last_name: "last"
nationality: null
place_of_birth: null
ranking_by_class: 0
ranking_by_school: 0
registration_number: null
user_id: 238
}
Je suis en train de travailler sur le superadmin rôle au moment où je suis dans le besoin de données supplémentaires à partir de chaque étudiant (subscription_type
), qui est uniquement disponible sur GET /users/:id
Donc, quand je suis liste de 20 à 30 étudiants sur une page via l' GET /students/
, afin d'obtenir le subscription_type
, Je vais également besoin de faire 20 à 30 les demandes supplémentaires, une pour chaque élève.
J'ai parlé à l'API de gars à ce sujet et on m'a dit que, y compris les données supplémentaires dans students
"n'est pas le repos manière de faire", "il va ralentir le temps de réponse encore plus" et que "30 les demandes supplémentaires pèsent moins d'un gros morceau".
Je ne sais rien à propos de travailler sur une API, donc je ne peux pas vraiment dire, mais je suis fou de penser que 30 des demandes de chargement de la page est ridicule?
Alors que la prochaine?Dois-je aller de l'avant et effectuer les demandes supplémentaires?Faut-il séparer les réponses pour chaque rôle d'utilisateur et d'inclure seulement les choses dont j'ai besoin pour chaque rôle?Qu'est-ce que l' façon correcte de ce traitement?
La solution
Bien que, strictement parlant, l'API gars est correct, après le repos de l'évangile de manière trop stricte peut entraîner l'inefficacité comme le 1+N problème créé par les puristes de la mise en œuvre.Un concept clé en Reposant la conception est que les ressources n'ont pas de carte directement à des objets du domaine.Lors de la conception des ressources, on doit regarder les scénarios d'utilisation.Dans le super admin scénario, il semble que lorsque le client demande une collection de students
et il est aussi généralement ou toujours besoin de données à partir de users
, spécifiquement subscription_type
.Le modèle objet est clairement normalisé comme il se doit, mais cela ne veut pas dire que les ressources doivent être, ou doit toujours être.
Il ya un couple de différents modèles que j'ai utilisé pour faire des scénarios similaires plus efficace.Qui (si) s'appliquent dépend de la façon dont les ressources sont consommées par les clients.
Composite De Ressources
C'est la combinaison de tout ou partie de deux ou plusieurs objets de domaine (par ex. student
et user
) en une seule ressource.
Depuis tous les students
sont probablement aussi users
, vous pouvez inclure tout ou partie des données de l'utilisateur dans la ressource de l'élève selon le cas.
GET /students
{
address: null
class_id: 184
class_name: "I B"
date_of_birth: null
first_name: "first"
gender: null
grade: 1
id: 192
last_name: "last"
nationality: null
place_of_birth: null
ranking_by_class: 0
ranking_by_school: 0
registration_number: null
user_id: 238
subscription_type: "foo"
}
Ressources Liées Aux
(Semblable à une autre réponse) C'est une technique où le client peut indiquer qu'il veut une ressource connexe inclus dans la réponse.Ceci est particulièrement utile dans les "a" type de relation dans le modèle de domaine.Elle permet au client de essentiellement lazy load ou désireux de charge la ressource.
GET /students
{
address: null
class_id: 184
class_name: "I B"
date_of_birth: null
first_name: "first"
gender: null
grade: 1
id: 192
last_name: "last"
nationality: null
place_of_birth: null
ranking_by_class: 0
ranking_by_school: 0
registration_number: null
user_id: 238
}
GET /students?include_user=true
{
address: null
class_id: 184
class_name: "I B"
date_of_birth: null
first_name: "first"
gender: null
grade: 1
id: 192
last_name: "last"
nationality: null
place_of_birth: null
ranking_by_class: 0
ranking_by_school: 0
registration_number: null
user_id: 238
user:
{
id: 238
subscription_type: "foo"
...
}
}
Autres conseils
Vous avez deux problèmes ici, qui ne devrait pas être attachés ensemble - On est les données renvoyées pour chaque utilisateur de l'indice d'appel (ou d'étudiants), et l'autre est le processus d'autorisation qui doit déterminer les données d'un utilisateur peut être exposé.
Concernant la question des données - je ne pense pas qu'il y a une règle précise à suivre.Il dépend totalement de votre application à vos exigences.Si le subscription_type champ est généralement pas nécessaire, vous pouvez envisager l'adoption d'un paramètre de requête ('include_extra_data=1' par exemple) pour indiquer que vous en avez besoin, sur demande spécifique, où, par défaut, il ne sera pas retourné.
Concernant l'autorisation de la question - Ce qui devrait être totalement déconnectée de la données de votre demande sur votre demande.Le serveur doit être en mesure de déterminer les données qui est visible pour l'utilisateur en fonction de l'id d'utilisateur.(vous pouvez vérifier sur le CanCan gem][1] comme une solution possible).
Donc, en combinant les deux questions, de tout type d'utilisateur doit être en mesure de faire de l '/des étudiants de la demande avec ou sans le 'include_extra_data' drapeau.Si le serveur de l'utilisateur non autorisé à voir les données supplémentaires, vous pouvez choisir une des 2 options - Soit renvoyer uniquement les données que l'utilisateur est autorisé à voir, ou le retour d'un "401 unauthorized" réponse.
Les deux façons sont valides, et affecter la façon dont vous traitez avec la réponse sur votre application cliente.(Personnellement, je préfère le plus tard, car il est plus descriptif pour le client).
Espérons que cela aide :)