J'ai eu une discussion animée aujourd'hui au sujet de notre application MVC. Nous avons un site Web écrit en MVC ( ASP.NET ), et il suit généralement le modèle de faire quelque chose dans la vue -> appuyer sur le contrôleur -> le contrôleur construit un modèle (appelle un gestionnaire qui récupère les données, construit le modèle dans le méthode du contrôleur lui-même) -> modèle va voir -> rinçage et répéter.
Il a dit que notre code était trop étroitement lié. Par exemple, si nous voulions également une application de bureau, nous ne pourrions pas utiliser notre code existant.
La solution et la meilleure pratique, a-t-il déclaré, consiste à créer une API, puis à créer votre site Web au-dessus de votre API, puis à créer une application de bureau, une application mobile, etc. est très simple.
Cela me semble une mauvaise idée pour diverses raisons.
Quoi qu'il en soit, je ne trouve pas quoi que ce soit en googlant qui puisse discuter de cette pratique. Quelqu'un at-il des informations sur les avantages, les inconvénients, pourquoi vous devriez, pourquoi vous ne devriez pas ou une lecture plus approfondie?
Quelques raisons pour lesquelles je pense que c'est une mauvaise idée:
C'est beaucoup trop abstrait pour exécuter votre back-end d'une API. Vous essayez de le rendre trop flexible, ce qui en fera un gâchis ingérable.
Tout ce qui est construit dans MVC semble inutile, comme les rôles et l’authentification. Par exemple, les attributs [Autoriser] et la sécurité; vous devrez rouler le vôtre.
Tous vos appels d'API nécessiteront des informations de sécurité en pièce jointe, et vous devrez développer un système de jetons et ainsi de suite.
Vous devrez écrire des appels d'API complets pour chaque fonction que votre programme accomplira. Pratiquement toutes les méthodes que vous souhaitez implémenter devront être exécutées à partir d'une API. A Obtenir / Mettre à jour / Supprimer pour chaque utilisateur, plus une variante pour chaque autre opération, par exemple, mettre à jour le nom d'utilisateur, ajouter un utilisateur à un groupe, etc., etc., chacune d'elles constituant un appel d'API distinct.
Vous perdez toutes sortes d'outils comme les interfaces et les classes abstraites en matière d'API. Des choses comme WCF ont un support très ténu pour les interfaces.
Vous avez une méthode qui crée un utilisateur ou effectue une tâche. Si vous voulez créer 50 utilisateurs, vous pouvez l'appeler 50 fois. Lorsque vous décidez de faire cette méthode en tant qu'API, votre serveur Web local peut nommer des canaux nommés et aucun problème - votre client de bureau peut également y accéder, mais soudainement, la création en bloc d'un utilisateur impliquera de marteler l'API sur Internet 50 fois, ce qui n'est pas le cas. pas bien. Vous devez donc créer une méthode en bloc, mais vous ne la créez que pour les clients de bureau. De cette façon, vous finissez par devoir a) modifier votre API en fonction de son intégration, et vous ne pouvez pas simplement y intégrer directement, b) faire beaucoup plus de travail pour créer une fonction supplémentaire.
YAGNI . Sauf si vous envisagez spécifiquement d'écrire deux applications fonctionnant de manière identique, une application Web et une application Windows, par exemple, cela représente une énorme quantité de travail de développement supplémentaire.
Le débogage est beaucoup plus difficile lorsque vous ne pouvez pas parcourir de bout en bout.
De nombreuses opérations indépendantes nécessitant beaucoup de va-et-vient, par exemple, du code peut obtenir l'utilisateur actuel, vérifier que l'utilisateur est dans le rôle d'administrateur, obtenir la société à laquelle l'utilisateur appartient, obtenir la liste des autres membres, les envoyer à tous un courriel. Cela nécessiterait de nombreux appels d'API ou l'écriture d'une méthode sur mesure de la tâche spécifique que vous souhaitez, où le seul avantage de cette méthode sur mesure serait la rapidité, mais l'inconvénient serait qu'elle serait inflexible.
Probablement quelques autres raisons qui me viennent à l’esprit.
Il me semble que, sauf si vous avez vraiment besoin de deux applications identiques, cela ne vaut vraiment pas la peine. Je n'ai jamais vu une application ASP.NET construite comme celle-ci non plus, vous auriez à écrire deux applications distinctes (l'API et votre code) et à les contrôler toutes les deux aussi (si votre page utilisateur reçoit un nouveau champ, vous ' Il est nécessaire de mettre à jour l’API et votre code utilisateur simultanément pour éviter tout effet indésirable ou pour déployer beaucoup de travail supplémentaire afin de le maintenir robuste).
Edit: Quelques bonnes réponses, commencent vraiment à avoir une bonne idée de ce que tout cela signifie maintenant. Donc, pour développer ma question, comment structureriez-vous une application MVC pour qu'elle suive cette structure d'API?
Par exemple, vous avez un site Web qui affiche des informations sur un utilisateur. Sous MVC, vous avez:
View - Page HTML (CS) qui affiche un contrôleur UserViewModel - Appelle GetUser () et crée un UserViewModel qu'il transmet à la classe View Manager (sorte de votre API) comportant une méthode GetUser.
Le contrôleur effectue GetUser () mais vous souhaitez également une application de bureau. Cela signifie que votre GetUser doit être exposé via une sorte d'API. Vous voudrez peut-être une connexion TCP, WCF, ou peut-être Remoting. Vous voulez également une application mobile qui sera RESTful puisque les connexions persistantes sont irrégulières.
Alors, écririez-vous ensuite une API pour chaque service, un service Web WCF qui possède une méthode GetUser () et le code le fait return new UserManager().GetUser()
? Et une méthode mvc 4 web api qui fait la même chose? Tout en continuant à appeler GetUser directement dans votre méthode de contrôleur MVC?
Ou choisiriez-vous la solution qui fonctionnerait pour les trois services Web (service REST Web Api) et construiriez-vous le dessus?
Et s’agit-il d’un scénario théorique parfait? Je peux voir de gros frais généraux dans le développement de cette façon, surtout si vous devez développer de manière à vous permettre de faire des opérations de manière RESTful. Je pense qu'une partie de cela a été couverte dans les réponses.
Edit 2: Après avoir lu plus de choses, j'ai mis un commentaire ci-dessous que je pense pourrait l'expliquer. La question est un peu une question piège, je pense. Si vous écrivez votre back-end en tant qu'API, j'ai eu du mal à croire qu'il devrait exister un seul service Web qui appelle tout (applications mvc, applications de bureau, applications mobiles).
La conclusion à laquelle je suis arrivé est que vous devez réellement vous assurer que votre couche de logique métier est correctement découplée. En regardant mon code, je le fais déjà: le contrôleur fera appel GetUser()
à un gestionnaire, puis en créera un modèle de vue à restituer avec une vue. Alors vraiment, la couche de logique métier est une API. Si vous souhaitez l'appeler depuis une application de bureau, vous devez écrire quelque chose comme un service WCF pour faciliter l'appel. Le simple fait d'avoir une méthode WCF appelée GetUser()
contenant le code return MyBusinessLayer.GetUser()
serait suffisant. Donc, l'API est la logique métier, et WCF / web api, etc. ne sont que des fragments de code permettant aux applications externes de l'appeler.
Il y a donc un surcoût, dans la mesure où vous devez encapsuler votre couche de logique métier dans différentes API en fonction de vos besoins, et vous devez écrire une méthode API pour chaque opération que vous souhaitez exécuter avec vos autres applications. trier un moyen de faire l'authentification, mais pour la plupart c'est la même chose. Collez votre logique métier dans un projet séparé (bibliothèque de classes) et vous n'aurez probablement aucun problème!
Espérons que cette interprétation est correcte. Merci pour toutes les discussions / commentaires qu'il a générés.
la source
Réponses:
Oui tu devrais.
Cela rend non seulement votre arrière-plan réutilisable, mais permet plus de sécurité et une meilleure conception. Si vous écrivez votre système dans un seul système, vous créez un design monolithique qu'il n'est jamais facile d'étendre, de remplacer ou d'améliorer.
Microservices est l’un des domaines dans lequel cela est populaire à l’heure actuelle . Le serveur est divisé en de nombreux services (voire des services volumineux) fournissant chacun une API utilisée par le système client. Si vous imaginez utiliser de nombreuses sources de données tierces dans votre application, vous réalisez peut-être que vous le faites déjà.
Un autre avantage est que la construction et la maintenance de chaque service peuvent être confiées à une équipe différente, qui peut y ajouter des fonctionnalités qui n'affectent aucune autre équipe produisant un produit. Ce n'est que lorsqu'ils ont terminé et publié leur service que vous commencez à ajouter des fonctionnalités à votre produit pour les consommer. Cela peut rendre le développement beaucoup plus fluide (bien que potentiellement plus lent dans l’ensemble, vous auriez tendance à être de meilleure qualité et plus compréhensible)
Edit: OK je vois ton problème. Vous pensez à l'API comme une bibliothèque distante. Ce n'est pas. Pensez au service plutôt qu’à un service de fourniture de données. Vous appelez le service pour obtenir des données, puis effectuez des opérations sur ces données localement. Pour déterminer si un utilisateur est connecté, appelez "
GetUser
" puis examinez la'logged on'
valeur, par exemple. ( YMMV avec cet exemple, bien sûr).Votre exemple de création en bloc d’utilisateurs consiste simplement à trouver des excuses - il n’ya aucune différence, tout ce que vous auriez pu faire dans un système monolithique peut toujours être fait dans une architecture de service (par exemple, vous auriez passé un grand nombre d’utilisateurs à créer en bloc ou un seul à créer. Vous pouvez toujours faire exactement la même chose avec les services).
MVC est déjà basé sur le concept de services isolés, seuls les frameworks MVC les regroupent dans un seul projet. Cela ne signifie pas que vous perdez quoi que ce soit, à l'exception des aides groupées fournies par votre framework. Utilisez un cadre différent et vous devrez utiliser des aides différentes. Ou, dans ce cas, faites rouler les vôtres (ou ajoutez-les directement à l'aide d'une bibliothèque).
Le débogage est également simple: vous pouvez tester l'API de manière approfondie de manière à ne pas avoir à le déboguer (et déboguer de bout en bout, Visual Studio peut se connecter simultanément à plusieurs processus).
Des choses comme un travail supplémentaire pour la sécurité sont une bonne chose. Actuellement, si vous intégrez tout le code dans votre site Web, si un pirate informatique y accède, il aura également accès à tout, base de données comprise. Si vous le divisez en une API, le pirate informatique ne peut que faire très peu avec votre code, à moins de pirater également la couche d'API - ce qui sera extrêmement difficile pour eux (ils se sont jamais demandé comment les attaquants obtiennent de vastes listes de tous les utilisateurs du site ou des détails cc? C'est parce ils ont piraté le système d'exploitation ou le serveur Web et celui-ci disposait d'une connexion directe à la base de données où ils pouvaient "
select * from users
" s'exécuter facilement ".Je dirai que j'ai vu de nombreux sites Web (et applications client-serveur) écrits de la sorte. Lorsque je travaillais dans le secteur des services financiers, personne n’écrivait jamais un site Web tout-en-un, en partie parce qu’il s’agissait d’un risque de sécurité excessif et en partie du fait qu’une grande partie du développement constituait de jolies interfaces graphiques associées à un traitement de données final stable systèmes. Il est facile d'exposer le système DP en tant que site Web utilisant une architecture de style service.
2nd Edit: Quelques liens sur le sujet (pour l'OP):
Notez que lorsque vous parlez de ces éléments dans le contexte d’un site Web, le serveur Web doit être considéré comme la couche présentation, car c’est le client qui appelle les autres niveaux et également parce qu’il construit les vues de l’interface utilisateur envoyées au navigateur pour le rendu. C’est un sujet complexe, et il existe de nombreuses façons de concevoir votre application - centrée sur les données ou centrée sur le domaine (j’estime généralement que le centré sur le domaine est plus pur, mais YMMV ), mais il s’agit tout simplement de maintenir un niveau logique entre votre client et votre base de données. C'est un peu comme MVC si vous considérez que le niveau intermédiaire, API, correspond à votre modèle, seul le modèle n'est pas un simple wrapper pour la base de données, il est plus riche et peut faire beaucoup plus (par exemple, des données agrégées provenant de 2 sources de données, post - traiter les données pour les adapter à l'API, les mettre en cache, etc.):
la source
Vous ne pouvez pas éventuellement éviter de construire une API . Même si vous construisez "juste un site Web", il devra quand même extraire ses données de votre backend. Quoi que vous fassiez, c'est votre API de facto .
Sachant cela, la vraie question n'est pas de savoir si une API doit être construite, mais comment la construire . Vous pouvez le faire sur la volée comme ad hoc chose -et en effet, de nombreux sites sont construits exactement ce Way- ou vous pouvez concevoir soigneusement pour être utilisable dans d' autres contextes. Placé dans ce contexte, il devient assez clair que votre collègue a raison: vous devez d'abord faire l'API, puis créer votre site par dessus.
Néanmoins, cela soulève certaines inquiétudes, comme vous le signalez. Pour y répondre:
Cela dépend de la façon dont vous le faites. Comme le souligne George Pólya dans son excellent texte Comment résoudre ce problème , il est fréquent que "le problème plus général soit plus facile à résoudre". C'est ce qu'on appelle le paradoxe de l' inventeur . Dans le cas de la programmation, cela fonctionne souvent en séparant les préoccupations: votre back-end n'a plus à se préoccuper du format des données qu'il entre et en sort, son code peut donc être beaucoup plus simple. Vos analyseurs de données et vos moteurs de rendu n'ont plus besoin de se préoccuper de ce qu'il advient des données qu'ils créent, ils peuvent donc aussi être plus simples. Tout fonctionne en décomposant le code en morceaux plus gérables.
J'avoue que j'ai beaucoup de mal à sympathiser avec les personnes qui refusent d'apprendre leurs outils. Le fait que vous ne compreniez pas que leur utilisation ne signifie pas qu’ils sont inutiles et que cela ne signifie certainement pas que vous deviez le faire vous-même . Bien au contraire; vous ne devriez pas utiliser vos propres outils avant d'avoir compris les alternatives, afin de pouvoir vous assurer de résoudre les mêmes problèmes (même si ce n'est que de votre propre chef).
Pensez à Linus Torvalds , qui est le plus connu pour écrire Linux , mais qui a aussi écrit git : il est maintenant l’un des systèmes de contrôle de version les plus populaires au monde. L'un des facteurs déterminants de sa conception était une opposition profonde à Subversion (un autre VCS extrêmement populaire et sans doute le plus populaire à l'époque où git a été écrit); il résolut de prendre tout ce que Subversion pourrait, et dans la mesure du possible, de résoudre ces problèmes différemment. Pour ce faire, il devait devenir lui-même un expert de Subversion , précisément pour pouvoir comprendre les mêmes problèmes et adopter une approche différente.
Ou, au cours de l'apprentissage de vos outils, vous constaterez peut-être qu'ils sont utiles tels quels et qu'ils n'ont pas besoin d'être remplacés.
Oui. Ça devrait être comme cela.
Pas nécessairement. C'est ici qu'interviennent des architectures telles que REST . Vous identifiez les ressources avec lesquelles votre application fonctionne et les opérations qu'il est judicieux d'appliquer à ces ressources, puis vous les implémentez sans vous soucier des autres .
Au contraire, les interfaces deviennent beaucoup plus importantes lorsque vous utilisez une API, pas moins . Ils apparaissent dans les représentations que vous les rendez. De nos jours, la plupart des gens spécifient un format basé sur JSON , mais vous pouvez utiliser le format de votre choix, à condition de bien le spécifier. Vous restituez la sortie de vos appels vers ce format sur le backend et vous l'analysez dans ce que vous souhaitez (probablement le même type d'objet) sur le frontend. Les frais généraux sont faibles et les gains de flexibilité sont énormes.
Créer une version en bloc d'une méthode existante est difficilement ce que j'appellerais "beaucoup plus de travail". Si vous ne vous inquiétez pas pour des choses comme l’atomicité, la méthode du volume peut ne pas être beaucoup plus qu’une interface très fine pour l’original.
Non, YANI (vous en avez déjà besoin). Je l'ai décrit comme ci-dessus. La seule question est de savoir combien de travail de conception doit y être consacré.
Pourquoi ne serais-tu pas capable de parcourir de bout en bout?
Mais plus précisément, le fait d’examiner les données dans un format facilement reconnaissable qui élimine tout le contenu de l’affichage tend à rendre le débogage plus facile , et non plus difficile.
REST résout ce problème en travaillant sur des objets complets ( ressources , pour utiliser les termes de la théorie REST), plutôt que sur les propriétés individuelles des objets . Pour mettre à jour le nom d'un utilisateur, vous devez obtenir l'objet utilisateur, en changer le nom et le remettre à zéro. Vous pouvez également apporter d'autres modifications en même temps que le nom d'utilisateur. Le problème plus général devient plus facile à résoudre, car vous pouvez éliminer tous ces appels individuels pour la mise à jour des propriétés individuelles d'un objet: il vous suffit de le charger et de le sauvegarder.
D'une certaine manière, cela n'est pas sans rappeler les architectures RISC du côté matériel. L'une des principales différences entre RISC et CISC (son prédécesseur) réside dans le fait que les architectures CISC ont tendance à inclure de nombreuses instructions qui fonctionnent directement en mémoire, alors que les architectures RISC ont tendance à fonctionner principalement dans des registres: dans une architecture purement RISC, les seules opérations en mémoire sont les suivantes: LOAD (copier quelque chose de la mémoire dans un registre) et STORE (prendre une valeur dans un registre et la mettre en mémoire).
On pourrait penser que cela impliquerait de faire beaucoup plus de trajets de registres en mémoire, ce qui ralentirait la machine. Mais dans la pratique, l’inverse se produit souvent: le processeur (client) effectue plus de travail entre les allers-retours en mémoire (serveur) , et c’est d’où l’accélération.
Longue histoire courte: votre collègue a raison. C'est le chemin à parcourir. En échange d'un peu de travail en amont, cela simplifiera considérablement le code de votre site Web et permettra une meilleure intégration avec d'autres sites Web et applications. C'est un prix qui vaut la peine d'être payé.
Lectures complémentaires:
la source
Je sais que les microservices font fureur à l'heure actuelle, mais ils n'en valent pas toujours la peine. Oui, l'objectif est un code faiblement couplé. Mais cela ne devrait pas se faire au détriment d'un cycle de développement plus douloureux.
Un bon moyen serait de créer un projet de données distinct dans votre solution. Le projet de données serait une bibliothèque de classes .NET. Votre projet ASP.NET MVC ajouterait alors une référence à la bibliothèque de données et tous les modèles seraient extraits du projet de données. Ensuite, lorsque le moment est venu de créer un bureau ou une application mobile, vous pouvez référencer le même code. Donc, ce n'est peut-être pas une API officielle, mais cela fonctionnera comme telle. Si vous souhaitez le rendre accessible en tant qu'API, vous pouvez créer un projet Web simple qui agit comme un wrapper sur le projet de données.
Microsoft a fait la promotion de ce concept, qu’ils appellent des bibliothèques de classes portables .
la source
Non tu ne devrais pas . Si vous ne prévoyez pas immédiatement de créer des interfaces alternatives (telles que des applications mobiles ou de bureau ou des applications Web distinctes) qui accèdent au même serveur, vous ne devez pas introduire de couche de service Web. YAGNI .
Un couplage lâche est toujours souhaitable (avec une cohésion élevée), mais il s'agit d'un principe de conception qui ne signifie pas que vous devez séparer physiquement les objets sur des serveurs différents! De plus, une API de service mal conçue peut créer un couplage étroit entre les serveurs, de sorte qu'une API ne garantit pas un couplage lâche.
Si le besoin d'une API de service devait apparaître à l'avenir, vous pouvez toujours l'introduire à ce moment-là. Tant que votre code reste bien stratifié (accès aux données et logique métier clairement séparés de la logique de l'interface utilisateur), il ne sera pas plus difficile de les introduire plus tard que maintenant. Et la conception résultante sera bien meilleure si elle est conçue pour répondre aux exigences réelles.
Remarque: Je suppose que la question est de savoir si vous devez créer une API de service Web ou non. La question dit simplement API, mais API peut aussi simplement désigner l'interface d'une bibliothèque, et bien entendu chaque couche aura une API par définition. En bout de ligne, vos couches de logique métier et d'accès aux données doivent être clairement séparées de la logique de l'interface utilisateur au niveau de la conception, mais vous ne devez pas introduire de couche de service Web si vous n'en avez pas besoin.
la source
Ma société a une application construite comme celle-ci. Initialement, nous avions été chargés de créer un back-end avec une API pour un front-end créé par un autre développeur. Lorsque l'autre développeur n'a pas pu développer ce front-end, nous avons également été chargés de le construire. Bien que cette approche présente des avantages indéniables, son inconvénient est énorme: son coût. La construction initiale coûtera beaucoup plus cher et la maintenance en cours le sera davantage, en raison de la quantité de code à maintenir et du déploiement de deux systèmes distincts. En raison des coûts supplémentaires, cela devrait toujours être une décision commerciale, et non prise sur un coup de tête par les développeurs.
Pour chiffrer cela, j’estimerais que le projet mentionné plus haut coûte 20% de plus grâce à cette approche. Vous ne décrivez pas le type de projet sur lequel vous travaillez et le type de société pour laquelle vous travaillez, mais si vous êtes un débutant dans la construction de leur produit, ce coût supplémentaire pourrait faire la différence entre la livraison de quelques fonctionnalités supplémentaires qui en font le produit. un succès.
Une autre raison de ne pas, du moins pas universellement, est que si ou lorsque vous décidez de créer cette seconde interface, il existe rarement un mappage de fonctionnalités un à un. Si vous créez une application mobile, par exemple, elles ont généralement moins de fonctionnalités. Cela signifie que certaines de vos méthodes d'API ne seront jamais réutilisées. Par conséquent, un compromis avec votre collègue pourrait consister à choisir entre vous les appels les plus cruciaux / critiques et à les ajouter à une API, et à utiliser des méthodes plus traditionnelles pour tout le reste.
Un autre point à considérer est que votre collègue dit que vous ne pourrez pas réutiliser votre code existant, ce qui n’est pas vrai si vous séparez quelque peu votre logique d’entreprise. Vous devez simplement créer un wrapper de service Web léger autour de vos API internes, ce qui n’est pas une tâche particulièrement lourde. Il serait naïf de penser que vous pourriez de toute façon réutiliser une couche de service Web pour un autre serveur frontal sans aucun changement.
la source
Cela dépend du type d'application et du type de marché dans lequel vous vous trouvez.
Il y a des compromis et des avantages à aller dans cette direction. Il n’est pas clair que l’une des méthodes est meilleure que l’autre.
Je parlerai de mon expérience personnelle. C’est moi qui ai décidé de prendre la base de code sur laquelle je travaillais dans cette direction en 2007. Cette base de code est actuellement de l’ordre d’un million de lignes de code, dont la moitié est un code serveur caché derrière une quantité énorme de services Web. Les APIs, l’autre moitié est une flottille de clients, de postes de travail natifs, de postes de travail Web, d’intégrations mobiles, dorsales, etc. . Permettez-moi d'indiquer certains des compromis en cause.
Avantages
Souplesse. Qu'il s'agisse d'une demande de création d'une application mobile pour améliorer l'expérience de bureau ou d'une demande d'intégration avec le back-end de SAP, tout devient plus facile quand vous avez déjà une API à appeler. Lorsque vous aurez assez de ces demandes, vous évoluerez de manière organique vers une API. La seule question à résoudre est de savoir si un service Web standard est en face de lui ou s'il s'agit d'une API interne dans laquelle les services Web sont conçus sur mesure.
Evolutivité (de l'équipe). Dans notre cas, nous avons de nombreux groupes de développeurs différents, tous construits au-dessus de cette API. Nous avons même des équipes d’API dédiées, qui discutent avec les différents groupes, résument les besoins et construisent une API polyvalente. Nous en sommes maintenant au point où on ne nous dit même plus que les gens construisent des éléments en plus de l'API, et que tous ceux qui le font ne travaillent pas pour notre entreprise.
Sécurité. Avoir une division claire entre les parties dangereuses et non sécurisées de votre base de code est utile pour raisonner sur la sécurité. Confondre l’interface utilisateur et le code d’arrière-plan tend à confondre les choses.
Compromis
Souplesse. Vous devez faire le travail pour construire "correctement" quelque chose dans l'API. Il n'est pas possible d'exécuter rapidement une requête de base de données à partir du code de l'interface utilisateur pour résoudre un problème spécifique. De plus, les API qui sont réellement réutilisables doivent prendre en compte tellement de cas d'utilisation que la solution rapide est généralement la mauvaise solution. L'API devient moins flexible pour évoluer, d'autant plus qu'il y a déjà beaucoup de code client (nous sommes en train de passer à une API versionnée pour cette raison).
Vitesse de développement initiale. Il est plus lent de développer API-first, sans aucun doute. Vous ne le récupérerez que si vous avez suffisamment de clients construits sur l'API. Mais vous constatez alors que vous avez besoin de 3 implémentations client différentes avant que votre API ne devienne suffisamment générique. Nous avons constaté que la plupart de nos conceptions d’API initiales étaient erronées et nous avons dû réviser nos instructions pour construire des services Web.
harengs rouges
Vous en avez mentionné beaucoup. Ils ne comptent pas vraiment dans la pratique.
Abstraction. Votre API devient suffisamment abstraite pour couvrir tous les cas d'utilisation que votre produit doit servir, sans plus. Même sans services Web, vous aurez soit une API interne qui le fera, soit beaucoup de code en double. Je préfère l'abstraction à la duplication.
Abandon de la pile MVC côté serveur. Ces jours-ci, presque tous les systèmes auront besoin d’une application mobile au bout d’un moment. Lorsque vous créez ensuite des services Web adaptés à cette application mobile, vous devez quand même déterminer comment procéder à l'authentification et à l'autorisation dans un contexte d'API. C’est en fait moins de travail lorsque vous n’avez qu’une façon de le faire, comme vous le faites dans vos services Web.
Opérations en vrac. Généralement résolu en créant une API en bloc qui lance un travail principal et renvoie un ID de travail pour l'interrogation de l'état. Ce n'est pas si grave.
Débogage. J'ai trouvé que dans l'ensemble, il devenait légèrement plus facile de dépanner le système. Vous pouvez toujours définir des points d'arrêt dans les codes frontaux et finaux. Ainsi, dans la pratique, il n'est pas si difficile à parcourir et vous pouvez créer des tests api automatisés et les instrumenter pour surveiller les systèmes de production.
Beaucoup d'opérations indépendantes. Cela dépend de la façon dont vous concevez les choses. Si vous insistez pour avoir une API CRUD pure, alors oui, vous souffrirez de ce problème. Cependant, il est généralement utile d’avoir des API CQRS à augmenter. Si vous vous êtes assuré de disposer d’une API interne pour laquelle les services sont frontaux, vous pouvez facilement réutiliser cette API interne pour créer des services pour ces applications spécifiques. scénario de.
En résumé
Dans un système utilisé dans suffisamment de contextes différents, une API évoluera naturellement car il s’agit du moyen le plus simple de répondre à tous les besoins. Mais il y a certainement un cas de YAGNI en cours. Il y a des compromis et cela n'a pas de sens tant que cela n'a pas de sens. Le point clé est de ne pas être dogmatique et de rester ouvert aux différentes approches en architecture pour répondre aux besoins en évolution du produit.
la source
Ce que votre collègue décrit est une architecture orientée services. Cela peut être un moyen extrêmement codable, testable et sain de code, mais cela dépend vraiment de ce que vous faites.
La SOA présente d’importants avantages que je vais essayer d’énumérer:
L'évolutivité
Comme votre back-end est découplé, votre front-end devient juste une série de modèles, même des fichiers à plat. Les fichiers plats sont extrêmement rapides et peu coûteux à servir à partir de n’importe quel CDN. Ils peuvent être décomposés et précompilés en HTML statique, puis renseignés avec les données clients.
Votre API doit rester cohérente, mais peut être remplacée par une technologie plus rapide sans vous ruiner si vous dépassez votre technologie existante. Vous pouvez le refaire dans Go par exemple. Vous pouvez le reconstruire au cas par cas et répartir la charge sur les serveurs. Tant que l'interface reste la même, la technologie est abstraite.
Testabilité
MVC commence généralement de manière propre, mais dans la pratique, les contrôleurs restent rarement concentrés sur une seule ressource. Plus vos méthodes de contrôleur font de choses, moins elles deviennent testables.
Une API contourne ce problème. Chaque appel d'API extrait une ressource et la sert. Propre et testable.
Séparation garantie des préoccupations
Votre front-end et votre back-end sont entièrement divorcés. Vous pouvez donner le front-end à un autre développeur ou à un concepteur. C'est MVC pris à un autre niveau. Je suis sûr que vous ne voudriez pas abandonner MVC. SOA est MVC mais plus encore.
Inconvénients
Il y a bien sûr des inconvénients. Un monolithe est souvent plus rapide à utiliser. C'est peut-être ce à quoi vous êtes habitué. Cela s'intégrera peut-être mieux dans votre pile. Vos outils peuvent être optimisés pour la création de monolithes.
À mon avis, aucune de ces raisons n'est particulièrement valable, et vous voudrez peut-être envisager de procéder à un réoutillage si elles vous concernent.
la source
Il y a beaucoup de bonnes réponses ici donc je vais simplement ajouter mon expérience de mise en œuvre.
Voici comment je fais les choses:
interface
(virtual class
) qui expose / applique les fonctions API dont j'ai besoin. Une fois implémentés, ils utiliseront les fonctions hautement spécialisées de DBAL pour obtenir les résultats. Cela m'aide également à appliquer l'API au niveau du compilateur afin de m'assurer que l'implémentation Server + API intègre toutes les fonctions intégrées.Donc, techniquement, l’API est la deuxième couche. Vous l'utilisez directement avec le site Web et l'exposez à des clients distants via un serveur. Le code est réutilisé et aucun bloc de code réutilisable n'est jamais en ligne. (Vivre et mourir selon cette règle et tout est génial) Aide à la maintenabilité, aux tests ... à tout.
Vous ne connectez jamais le site Web au serveur API desktop / mobile (sauf si votre site est AJAX et s'exécute en JSON) . Mais si le site rend le contenu dynamique dans le balisage, le passage par une API intermédiaire tirera votre performance. Le site web doit être rapide! L'accès au client distant peut être un peu plus lent.
PS : Oui, la maintenance est un peu plus complexe car plus de roues fonctionnent ensemble, mais c'est plus facile à long terme. Donc, si votre projet est censé durer un certain temps et qu'il est légèrement complexe, utilisez toujours une API. Il est également beaucoup plus facile de tester chaque couche seule.
la source
Le problème n'est pas de savoir si vous devez utiliser une API, mais plutôt ce qu'est une "API". La seule alternative à l'utilisation d'une API conçue est d'utiliser une API qui est un désordre aléatoire de code. Vous écrivez qu'une API rend les choses "trop flexibles", ce qui les rend ingérables. Cela indique une incompréhension complète et approfondie de ce qu'est une API. Si ce malentendu n'est pas partagé entre vous et votre collègue, vous perdez beaucoup de temps en argumentant sur des choses complètement différentes.
En n'utilisant pas une API bien définie, vous pouvez faire ce que vous voulez. Par définition, c'est l'option la plus flexible. En outre, par définition, "faites ce que vous voulez" est toujours une API. Le seul travail d'une API est de supprimer la flexibilité. En supprimant la flexibilité, une bonne API encourage un utilisateur à faire des choses similaires de la même manière.
Bien sûr, une mauvaise API peut offrir trop ou trop peu de flexibilité, voire les deux à la fois. Une API vraiment mal conçue peut tuer un projet encore plus rapidement que l'approche "tout va bien". Cependant, la meilleure pratique consiste simplement à avoir des programmeurs compétents qui développent et font évoluer l'API parallèlement à votre application.
Exemple
Le nombre d'appels d'API nécessaires sur une API décente serait probablement de 1. Oui, c'est inflexible, mais pourquoi voudriez-vous qu'elle soit flexible?
la source
Et bien Si ce n'est pas le cas, c'est une déclaration plutôt dénuée de pertinence.
Je dirais que si vous deviez créer une nouvelle application en 2015, examinez sérieusement quelque chose avec une interface utilisateur qui implique une API et non des pages HTML générées par le serveur. Il y a des coûts évidents mais aussi des avantages évidents.
Mais si vous avez un site existant sans aucun plan concret pour avoir plusieurs interfaces différentes (pour autant que je sache), ses commentaires sont tout simplement hors de propos.
la source
Version courte: Votre contrôleur est une API efficace, peu importe quoi; bien que ASP.NET puisse obscurcir cela.
Version plus longue:
Pensez à une application Web MVC de base qui fournit des informations sur la bière et vous en vend éventuellement une. A quoi ressemblent les itinéraires?
Dans une application Web normale, il existe probablement plusieurs itinéraires auxiliaires, tels que:
Dans une API Web, ils ne sont pas obligatoires, car ils sont déduits de la méthode HTTP.
Compte tenu de la symétrie ci-dessus, je pense que cela prouve de manière assez convaincante que votre API et votre contrôleur sont si proches qu'ils peuvent aussi bien être la même chose.
Après avoir creusé un peu, j'ai déterminé qu'il pourrait s'agir de votre situation en fonction de la version d'ASP.NET utilisée. L'ancien MVC 5 et les versions antérieures ne disposent pas des conventions et de l'interface nécessaires pour unifier les deux implémentations. Dans les anciennes versions, Web App renvoie une vue alors que l'API donne une réponse HttpResponse. Dans les deux cas, ils génèrent exactement la même réponse sémantiquement.
Si vous utilisez MVC 6, vous obtenez les deux dans une classe de contrôleur unifié qui peut être intelligente quant à ce qu’elle renvoie. Je n'ai pas trouvé de bon exemple de code ASP pour ce modèle, mais j'ai trouvé du code Rails avec le même motif. Considérez ce contrôleur pour les "j'aime" du projet de la diaspora . Chaque méthode de commande a des itinéraires définis par une « convention de ressources » ici ce montant à la LCRUD dans une API.
Cependant, si vous lisez les implémentations, chacune peut éventuellement répondre à HTML, HTML mobile ou JSON. Ceci, combiné à une convention pour rechercher les vues, unifie complètement l'application Web et l'API Web. Vous remarquerez également que toutes les méthodes ne fournissent pas réellement chaque réponse (ce qui est logique, car l'interface utilisateur peut nécessiter des méthodes que l'API ne voudra pas, et vice versa).
Ceci est un décalage d'impédance car ASP.NET a en quelque sorte compris tout cela tardivement, alors que Rails a adopté la symétrie pendant un certain temps et l'a très bien expliqué.
Spéculation:
Votre collègue a probablement raison et tort, selon la version ASP utilisée. Sous l'ancienne version de MVC, la différence entre l'API et l'Application en faisait probablement une "pratique recommandée" pour la construction initiale de l'API, car le modèle ASP.NET ne permettait pas vraiment une bonne réutilisation du code.
Avec la version la plus récente, il est plus logique d’utiliser un code unifié, car il est désormais plus facile de le réutiliser avec la classe de base du contrôleur unifié.
Dans les deux cas, cependant, le contrôleur est effectivement l'API.
la source
Lorsque j'ai commencé ma carrière en 2006, ce type d'architecture faisait fureur dans le monde .NET. J'ai travaillé sur 3 projets distincts conçus au milieu des années 2000 avec un service Web entre la couche de logique métier et l'interface Web. Bien sûr ces jours-ci, les services Web étaient SOAP mais c'est toujours la même architecture. Les avantages supposés étaient la possibilité de basculer en avant ou en arrière et même de développer un programme de bureau. En fin de compte, YAGNI s'est avéré être vrai. Je n'ai jamais rien vu de tel arriver. Pendant tout ce temps, je n'ai vu que le coût de la scission du projet de cette façon. J'ai même fini par extraire le service Web de l'un des projets (il a fallu six mois pour le supprimer étape par étape tout en effectuant d'autres tâches) et toute l'équipe était heureuse. Je n'ai jamais essayé cette approche depuis et je ne le ferai pas à moins d'une raison très précise. Cinq années d'expérience à essayer cette architecture m'ont appris que je n'en aurai pas besoin et qu'aucun expert ne me dira le contraire qui me convaincra de le faire. Seul un projet dont j'ai besoin peut le faire.
Cela dit, j’essaie de développer une couche entre la logique d’entreprise et les contrôleurs / présentateurs. Par exemple, j'ai une couche de services, je n'expose jamais les variables, utilise les interfaces pour tous mes services et les injecte dans les contrôleurs avec IoC. Si j’ai besoin d’un service Web dans mon architecture, je pourrai le présenter à un coût raisonnable. Je ne veux tout simplement pas payer ce coût à l'avance.
De plus, j'aime bien l'idée de microservices mais je comprends que microservices désigne des modules verticaux plutôt que des couches horizontales. Par exemple, si vous construisez Facebook, la fonctionnalité de discussion en ligne constituera un service distinct déployé séparément sur ses propres serveurs, etc. C'est le type de services indépendants que j'encouragerais.
la source
Des tiers l'utiliseront? Oui, vous devriez .
Vous envisagez de le réutiliser dans un avenir pas si lointain? Oui tu devrais.
Vous serez votre tierce partie ; disposer d'une API documentée - ou documentable - ou utilisable par des tierces parties vous assurera une réutilisabilité et une modularité solides.
Vous êtes pressé? Non tu ne devrais pas.
Refactoriser ensuite est plus facile et plus rapide que la plupart des méthodologies et des enseignants prédisent et racontent. Il est plus important d'avoir quelque chose qui fonctionne (même avec une mauvaise conception interne, car il peut et sera refactoré) plutôt que de ne rien avoir du tout. (mais avec un design interne incroyable , wohoo)
Le front-end pourrait ne jamais voir la lumière du jour pour des raisons? Oui, vous devriez .
J'ai ajouté cette raison parce que, bien, cela m'est souvent arrivé.
Et au moins il me reste avec mes composants à réutiliser et à redistribuer, etc.
la source
Il y a de bonnes réponses ici. Je poste ceci comme une réponse partielle; ce serait peut-être mieux comme commentaire. Cependant, coller le même commentaire sur de nombreux posts n'est pas bon.
On ne peut pas prétendre que YAGNI est une raison pour ne pas créer une API.
L'API est un noeud final de test naturel et logique. Ainsi, dès le jour 0, deux applications utilisent l'API: l'interface utilisateur et la suite de tests. L'un est destiné aux humains, l'autre aux machines. Ils sont nécessairement différents. Tester le comportement frontal est une tâche bien différente du test du comportement principal. Ainsi, les techniques, et probablement les outils, sont complètement différents. L'API permet d'utiliser le meilleur outil pour le travail. En outre, avec la séparation offerte par l'API, les testeurs frontaux n'ont pas à tester la fonctionnalité dorsale.
L'API aide également à garder les codeurs frontaux à l'écart des préoccupations des codeurs dorsaux, et inversement. Ce sont des compétences très différentes chez nous; L'API nous permet de nous concentrer là où nous sommes le plus forts.
la source