Où dois-je placer une demande d'API dans MVC?


25

Je crée une application Web en utilisant un modèle MVC. En suivant ce type d'architecture, nous pouvons voir que toutes les méthodes utilisées pour interagir avec la base de données sont implémentées dans le modèle .

Mais que se passe-t-il si je dois appeler un service exposé par d'autres sur le Web? Par exemple, j'aimerais accéder à l'API Facebook afin d'obtenir tous les abonnés de ma page, alors, où mettre ces méthodes?

Évidemment, la vue n'est pas une bonne idée car ce module est dédié à la présentation, le contrôleur ne doit pas être utilisé pour récupérer des données mais le modèle est généralement dédié uniquement à l'interaction avec la base de données.

Alors, pouvez-vous me donner un indice à ce sujet? Et s'il vous plaît, pouvez-vous me dire si je fais des erreurs sur l'architecture MVC?


2
Je pense que les gens seraient en mesure de fournir de meilleures réponses si vous répertoriez certaines des bibliothèques et des cadres que vous utilisez pour prendre en charge votre application MVC. Bien que le modèle MVC soit indépendant de la technologie, tous les cadres ne le suivent pas explicitement. De plus, la plupart des frameworks matures ont déjà une documentation exceptionnelle et savoir laquelle vous utilisez vous permettra de vous diriger plus facilement vers une explication préexistante qui suit votre ligne de pensée.
CLW

2
Base de données? La source de données? C'est juste des données.

2
Il y a tellement d'opinions sur ce que "MVC" est censé être, que cette question est trop abstraite pour y répondre.
RemcoGerlich

2
Pensez également à appeler l'API à partir de votre code Javascript frontal, et à ne pas le toucher du tout à votre "MVC" backend.
RemcoGerlich

@Remcogerlich c'est pourquoi j'ai proposé un ajout de l'implémentation réelle qu'il examine. Il pourrait avoir affaire à un backend et à une implémentation frontend de mvc. Nous pourrions également avoir un autre modèle en place qui explique mieux ces différences.
CLW

Réponses:


37

Le modèle n'est pas limité à l'interaction avec la base de données, le modèle est responsable de l'obtention et de la manipulation des données.

Donc, pour votre vue et votre contrôleur, cela ne devrait faire aucune différence, si les données proviennent d'une base de données ou d'un service Web ou sont même totalement aléatoires, vous devez donc le faire dans le modèle.

MVC est un modèle de présentation, qui ne sépare que les différentes couches de représentation.

Cela ne signifie pas que ce modèle doit être un gâchis uniforme de code de spaghetti. Votre modèle lui-même peut également être superposé, mais le contrôleur ne doit pas savoir d'où viennent les données.

Une méthode publique dans votre modèle peut être structurée comme ceci (pseudo-code), qui peut être appelée par votre contrôleur:

public MyDataClass getData(int id) {
    WebServiceData wsData = WebService->getData(id);
    DatabaseData dbData = ORM->getData(id);
    return new MyDataClass(wsData, dbData);
}

WebServiceet ORMpeuvent devoir être des instances d'interfaces qui peuvent être remplacées par des simulations via l'injection de dépendances, mais vos contrôleurs et vues n'ont pas besoin de changer à des fins de test.


8
Le modèle ne doit avoir aucune logique et ne doit donc interagir directement avec rien. Le modèle MVC appelle clairement à ce que toute la logique soit placée dans les contrôleurs. Ces contrôleurs doivent contacter la base de données, l'API, etc. au fur et à mesure de la mise à jour du modèle si nécessaire. Cela garde votre technologie de modèle agnostique et garantit qu'elle ne sert rien de plus qu'un mécanisme de stockage qui peut être transmis à diverses vues pour la présentation et des contrôleurs pour une manipulation supplémentaire.
CLW

3
@CLW: Model! = Modèle de données. Plus de détails peuvent être trouvés ailleurs, par exemple stackoverflow.com/a/14045514/124983
Residuum

2
@CLW: la logique métier ne doit pas être en M, V ou C. Les modèles sont l'abstraction d'un magasin de données, les vues et les contrôleurs sont votre interface utilisateur. Ils sont la périphérie de l'application que vous construisez, qui devrait être "juste du code", qui n'a pas besoin de connaître des choses comme les bases de données et le Web.
RemcoGerlich

2
La partie "modèle" est interprétée de plusieurs centaines de façons différentes. On m'a toujours appris qu'un modèle est une représentation. Un train miniature est une représentation d'un vrai train, avec de petites pièces mobiles qui se déplacent comme le vrai. De même, le modèle de votre application est une représentation des systèmes et des processus que vous créez votre logiciel à remplacer. En tant que tels, les modèles ont un comportement . Ce comportement intègre votre "logique métier". Ainsi, lorsque vous ignorez l'accès aux données CRUD, l'interface utilisateur et l'interopérabilité, ce qui reste est probablement votre "modèle" - classes de domaine, règles commerciales, etc.
anaximander

1
@RemcoGerlich Je n'ai rien dit sur la logique métier. J'ai simplement déclaré que puisque la plupart des interprétations de MVC appellent le modèle à n'être rien d'autre qu'une simple structure représentant l'état de votre application, la responsabilité de contacter la base de données, l'API, etc. ne devrait pas être placée dans le modèle car il devrait être sans logique. Le devoir de communiquer avec la base de données devrait incomber au contrôleur ou à un autre objet géré par le contrôleur.
CLW

12

Il y a un malentendu commun (intentionnel?) Sur ce que sont M, V et C. Pas sur les rôles qu'ils jouent, mais quels sont- ils.

Dans la définition originale de l'interface graphique de bureau de MVC, il s'agissait de modules . Typiquement, une application en avait plusieurs, travaillant parfois en triplets, ayant parfois une variété de vues et de modèles que quelques contrôleurs pouvaient mélanger et assortir.

Dans les frameworks Web, OTOH, ils ont tendance à être vus comme des couches , où ils ne sont qu'un de chacun et traitent principalement de la couverture d'un certain niveau d'abstraction sous-jacente: "la couche modèle résume la base de données", "la couche vue implémente la présentation", "le contrôleur couche traite les entrées utilisateur ".

Donc, je dirais que vous avez déjà un modèle, dédié à l'interaction avec la base de données, et que vous n'avez maintenant qu'à créer un autre modèle, pour gérer votre API source. Si vous les rendez aussi similaires que possible, la plupart du code du contrôleur et de la vue peuvent fonctionner de manière transparente avec l'un ou l'autre modèle.


1
D'accord: Le (s) modèle (s) ont toujours été supposés être l'ensemble du domaine problématique. Dans les applications compliquées, c'était toujours censé être la majeure partie du code. Ils étaient constitués de tout le code qui ne changerait pas si vous modifiez l'interface utilisateur (par exemple, du site Web à l'interface graphique ou même à l'application en ligne de commande). Pensez à un compilateur. Seule une très petite partie du code changerait si vous passiez d'une interface de ligne de commande à une interface graphique, ou même à une interface Web. Tous les tripes d'une telle application sont les modèles.
Kevin Cathcart

1
Dans l'utilisation originale du terme Smalltalk, chaque contrôle d'interface utilisateur dans l'interface avait son propre modèle, vue et contrôleur.
RemcoGerlich

5

Une partie de la difficulté avec toute discussion sur MVC est que différents groupes l'ont coopté pour signifier des choses différentes. L'implémentation de MVC utilisée, disons, dans une application Rails, serait presque méconnaissable pour quelqu'un qui écrit une application Swing. Dans la mesure où MVC est toujours une chose bien définie, il s'agit davantage d'un ensemble de principes directeurs (séparer l'application principale de sa représentation visuelle, fournir des mécanismes flexibles pour permettre aux deux d'être raccordés ensemble), qui peuvent être mis en œuvre dans divers façons.

En effet, il y a une tendance à donner des noms différents à des conceptions dérivées de MVC (voir cet article de Martin Fowler pour une discussion à ce sujet), ou même à renoncer à une dénomination précise - par exemple, AngularJS se décrit comme un modèle-vue-peu importe cadre.

Il est donc difficile de répondre sans savoir avec quelle version de "MVC" vous travaillez. Cependant, une demande d'API ferait généralement partie de l'application principale (la partie qui ne devrait pas changer si vous décidez d'utiliser une représentation visuelle différente), qui, dans de nombreuses implémentations, serait entièrement contenue dans le modèle.


2

Ici , le modèle est décrit comme ceci:

Un modèle stocke des données récupérées sur le contrôleur et affichées dans la vue. Chaque fois qu'il y a un changement dans les données, il est mis à jour par le contrôleur.

Je dirais que le contrôleur inclut la logique d'appeler le service ou appelle un Serviceobjet séparé . Si le service est distinct, vous pouvez plus facilement créer des tests, par exemple, si aucune connexion à un service sur un réseau n'est possible, certains TestServicepourraient fournir des réponses à partir du Servicelocal.

Consultez également cette réponse qui suggère que le contrôleur appelle le service.


2

Votre modèle ne doit jamais contenir de code réel et doit être considéré comme davantage un message ou une structure utilisée pour gérer le contenu manipulé par le contrôleur et affiché par la vue.

Votre contrôleur devrait être responsable de contacter toutes les API, bases de données, services, etc ... pour demander une modification et gérer les mises à jour nécessaires du modèle.

Toute la force du modèle MVC est qu'il dissocie la logique (le contrôleur) de la vue et de l'état (le modèle). Ce faisant, vous êtes maintenant assuré que seul le code dans le contrôleur peut créer des effets secondaires car la vue et le modèle ne sont tout simplement pas autorisés à apporter des modifications.

Il permet également une meilleure réutilisation du code car un modèle peut être partagé entre différents contrôleurs et vues.


4
Je pense que lorsque vous dites "modèle" ici, vous faites référence à "viewmodel", dont l'OMI est une autre chose. Un modèle de vue obtient des données du contrôleur vers la vue, et en tant que tel, il s'agit soit d'un détail d'implémentation de la vue, soit d'un aspect des communications entre la vue et le contrôleur qui ne rentre pas vraiment dans l'un ou l'autre (cela dépend de la façon dont vous le voyez). Le «modèle» dans MVC fait référence à un modèle de système - une représentation du système qui incorpore ses données, sa structure et son comportement. Le modèle est l'état et la logique; le contrôleur est ce qui provoque l'exécution de la logique et l'état change lorsque la vue est manipulée.
anaximander

@anaximander Non, je fais référence au modèle dans une interprétation assez stricte de MVC (voir Wikipédia, Microsoft MVC, modèles de conception en tête de tête, etc.). Dans ces cas, le modèle n'est rien de plus qu'une simple structure pour transmettre des données autour et il n'y a pas de modèle de vue. Bien que l'implémentation de Microsoft MVC ajoute divers attributs au modèle, c'est plus pour plus de commodité que tout. En fin de compte, le modèle MVC avait pour but de faciliter les bonnes pratiques de séparation des codes et de limiter les effets secondaires.
CLW

1

C'est peut-être loin d'ici, mais c'est ce que je pense des WebApps et du travail avec des API distantes [complexes] dans de nombreux cas:

Je voudrais en faire une classe (c'est-à-dire une bibliothèque de méthodes d'atténuation des données) au lieu d'un modèle (c'est-à-dire une pile de fonctions d'atténuation des données). Il semble qu'il agisse de manière plus transparente, plus logique / schéma agnostique, et vous pouvez l'utiliser n'importe où sans charger-> appeler un modèle / contrôleur lui-même chaque fois que vous voulez l'utiliser. La logique est toujours séparée, le point de données est toujours flexible, et il semble plus ouvert pour l'interopérabilité dans des cas étranges comme l'empilement clientAJAX-> appJSON-> appLIB-> remoteAPI-> remoteJSON etc. pour interroger le point de terminaison indirectement.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.