web-dev-qa-db-fra.com

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

Je crée une application Web à l'aide d'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?

Evidemment le voir 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?

25
Ema.jar

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);
}

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

37
Residuum

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

Dans la définition originale de MVC du bureau, il s'agissait de modules . Typiquement, une application en avait plusieurs, fonctionnant 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ù elles ne sont qu’une de chacune et s’occupent principalement de couvrir un certain niveau d’abstraction sous-jacente: "le la couche modèle résume la base de données "," la couche vue implémente la présentation "," la couche contrôleur 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 qu'il ne vous reste plus qu'à créer un autre modèle, pour gérer votre API source. Si vous les rendez aussi similaires que possible, la plupart du contrôleur et du code d'affichage peuvent fonctionner de manière transparente avec l'un ou l'autre modèle.

12
Javier

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 dans, disons, une application Rails, serait presque méconnaissable pour une personne qui écrit une application Swing. Dans la mesure où MVC est toujours une chose bien définie, c'est plutôt une 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 de différentes manières.

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-quel que soit le 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.

5
James_pic

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'appel du service ou appelle un objet Service distinct. Si le service est séparé, vous pouvez plus facilement créer des tests, par exemple, si aucune connexion à un service sur un réseau n'est possible, certains TestService pourraient fournir des réponses à partir du Service localement.

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

2
null

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.

2
CLW

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 agirait de manière plus transparente, plus logique/schéma agnostique, et vous pourriez 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.

1
dhaupin