2017-10-10 3 views
0

Comme constructeur REST API j'ai fait face à ce problème quelques fois sans une bonne solution:REST conception API pour l'entité cross requêtes

Avoir une organisation de l'entité, il semble clair que nous pouvons être le modèle comme/organisation avec tout le pack (GET, POSt, PUT, DELETE, filtrage, pagination, ...)

NOTEZ que j'utilise Spring avec les classes @RestController et PagingAndSortingRepository injecté dans le contrôleur.

Le problème commence par

/organisation/{id}/utilisateurs

qui est une URL parfaite pour une API REST, mais commence à causer une certaine douleur. Si nous suivons le chemin de traitement de la requête dans le contrôleur d'organisation, nous aurons besoin d'ajouter UserDAO au contrôleur, donc nous pouvons finir avec beaucoup de DAOS injectés dans chaque contrôleur, et chaque contrôleur responsable de renvoyer beaucoup d'objets différents: , utilisateurs, modèles, etc.

La résolution du problème sur la couche DAO n'est pas une solution; Essayer de faire que les dépôts retournent tous ces différents objets ne fonctionnera pas (PagingAndSortingRepository se plaindra si nous essayons de travailler avec des entités différentes) et cela ne semble pas être la bonne chose parce que nous forçons les dépôts à travailler avec des entités hors de son domaine. L'utilisation d'une couche intermédiaire entre les contrôleurs et les DAO pourrait fonctionner, une couche de service capable de contenir ces différents DAO et offrant une seule façade, mais encore une fois se trompe: d'abord le contrôleur fonctionne encore avec de nombreux objets différents domaine, Deuxièmement, nous avons une couche sans but réel qui peut croître avec des combinaisons de DAO, ou ayant un grand objet DAO maître capable d'interroger n'importe quoi.

Quelle est la bonne façon de résoudre ce problème?

Répondre

0

J'ai effectivement eu le même problème plusieurs fois et est venu avec une solution générique. Redéfinissons d'abord le problème: dans votre service ou votre contrôleur, vous devrez effectuer une action qui pourrait avoir différents types. (Dans votre cas, vous devez accéder à un objet qui, à différents moments, peut être un utilisateur, un modèle d'organisation ou autre chose.Chaque type d'accès est effectué par un bean séparé et il n'est pas souhaitable d'injecter tous ces haricots dans votre service/contrôleur.

La solution est un motif Factory Voici ce que j'ai fait: J'ai créé une interface et une classe abstraite implémentant cette interface pour l'action (dans votre cas, ce serait quelque chose comme GenericDao et GenericDaoImpl). Classe Factory (Say GeneralDaoFactory) Cette classe contient une carte Map<String, GenericDao> Dans ma classe générique, j'ai écrit un constructeur qui s'ajoute à l'Usine Factory reçoit un nom (généralement un nom de classe) et une instance de GenericDao et le place dans sa carte interne Ensuite, vous venez d'écrire vos classes implémentant GenericDaoImpl (OrganizationDaoImpl, UserDaoImpl etc) et m Assurez-vous qu'ils sont définis comme des haricots. Le ressort lors de l'initialisation instanciera tous les beans et chaque bean exécutant son constructeur se placera dans l'usine. Alors maintenant dans votre code dans votre contrôleur/service tout ce que vous devez faire:

GenericDao userDao = GeneralDaoFactory.getInstance("UserDaoImpl"); 
GenericDao organizationDao = GeneralDaoFactory.getInstance("OrganizationDaoImpl"); 

L'usine sera initialisé derrière les printemps par © mie, et vous n'avez pas besoin d'injecter un de ces daos à l'avance. Vous avez juste besoin de connaître leurs noms et savoir lequel vous avez besoin pour le moment.Aussi une fois que vous avez besoin d'ajouter un nouveau Dao, tout ce que vous devez faire est de actuially écrire son implementatin et il est désormais disponible auprès de votre usine

+0

mmm ... pas sûr de comprendre parce que vous injectez les deux DAO à la fin ... mais je pense que votre suggestion est peut-être d'avoir des contrôleurs génériques avec des DAO génériques et un mécanisme qui identifiera les DAO requis pour un demande et va instancier à l'exécution un contrôleur spécifique avec des DAO spécifiques pour répondre à cette requête spécifique. C'est ça? – Rafael

+0

@Rafael vous avez mal compris. Tout d'abord, pas de contrôleurs génériques - juste votre contrôleur habituel. Deuxièmement, aucun DAO n'est injecté du tout, ils sont simplement créés en tant que haricots au printemps mais ne sont pas injectés n'importe où. Mais vous avez une usine qui fait référence à eux - chaque bean se met dans la carte d'usine dans son constructeur. Puis dans votre contrôleur à l'exécution, vous pouvez obtenir n'importe quel DAO à travers l'usine –

0

Vous état /organization/{id}/usersest une URL parfaite pour une API REST.

C'est une URL raisonnable, mais je dirais que puisque l'URL traverse des domaines, ne peut être utilisé que pour la recherche.

En outre, une seule responsabilité est appliquée pour limiter le nombre de DAO par contrôleur. Le contrôleur de support pour l'URL ci-dessus serait quelque chose comme OrganizationUsersSearchController. Vraisemblablement, la méthode renvoie un List<User> users pour le id demandé. Cette classe interagit avec le OrganzationsDAO pour obtenir du contexte, et le contexte est transmis à UsersDAO pour obtenir la liste des utilisateurs. Les DAO peuvent être enveloppés par une classe de service, de sorte que le contrôleur n'est qu'une façade. Une fois que le client a la liste users, les opérations CRUD sont appelées par le client à l'aide de l'URL de domaine unique, telle que /users/{userId}. Le UserController n'interagit qu'avec le UsersDAO. Encore une fois, peut-être envelopper le DAO dans une classe de service de sorte que le contrôleur est juste une façade.

+0

"ne peut être utilisé pour la recherche." ... Je peux convenir que, semble toujours une URL de repos très solide. "la responsabilité unique est appliquée pour limiter le nombre de DAO par contrôleur" EXACTEMENT c'est le point de départ de la question. Maintenant ce que j'argument c'est qu'OrganizationUsersSearchController me semble être une mauvaise solution puisque le contrôleur va commencer à se multiplier ... nous finirons par avoir potentiellement beaucoup de contrôleurs ad-hoc afin de supporter ces opérations aussi le routage sera complexe depuis le départ de URl est le même. – Rafael