Ich hatte heute eine hitzige Diskussion über unsere MVC-Anwendung. Wir haben eine in MVC ( ASP.NET ) geschriebene Website, die normalerweise dem Muster folgt, in der Ansicht etwas zu tun -> Controller antippen -> Controller erstellt ein Modell (ruft einen Manager auf, der die Daten abruft, erstellt das Modell in der Controller-Methode selbst) -> Modell geht zur Ansicht -> Spülen & Wiederholen.
Er sagte, unser Code sei zu eng miteinander verbunden. Wenn wir beispielsweise auch eine Desktop-Anwendung benötigen, können wir unseren vorhandenen Code nicht verwenden.
Die Lösung und die beste Vorgehensweise, die er sagte, besteht darin, eine API zu erstellen und dann Ihre Website über Ihre API zu erstellen und dann eine Desktop-Anwendung, eine mobile App usw. zu erstellen. Dies ist sehr einfach.
Dies scheint mir aus verschiedenen Gründen eine schlechte Idee zu sein.
Wie auch immer, ich kann anscheinend nichts durch googeln finden, was über diese Praxis sprechen könnte. Hat jemand irgendwelche Informationen über Vor- und Nachteile, warum sollten Sie, warum sollten Sie nicht oder weiterlesen?
Einige Gründe, die ich für eine schlechte Idee halte:
Es ist viel zu abstrakt, um Ihr Backend über eine API auszuführen. Du versuchst es zu flexibel zu machen, was es zu einem unüberschaubaren Durcheinander macht.
Alles, was in MVC eingebaut ist, scheint nutzlos zu sein, wie Rollen und Authentifizierung. Zum Beispiel [Autorisieren] Attribute und Sicherheit; Sie müssen Ihre eigenen rollen.
Für alle Ihre API-Aufrufe sind angehängte Sicherheitsinformationen erforderlich, und Sie müssen ein Tokensystem entwickeln und so weiter.
Sie müssen vollständige API-Aufrufe für jede einzelne Funktion schreiben, die Ihr Programm jemals ausführen wird. Nahezu jede Methode, die Sie implementieren möchten, muss über eine API ausgeführt werden. Ein Get / Update / Delete für jeden Benutzer sowie eine Variante für jede andere Operation, z. B. das Aktualisieren des Benutzernamens, das Hinzufügen eines Benutzers zu einer Gruppe usw. usw., und jeder einzelne wäre ein eigener API-Aufruf.
Sie verlieren alle Arten von Werkzeugen wie Schnittstellen und abstrakte Klassen, wenn es um APIs geht. Sachen wie WCF unterstützen Schnittstellen nur sehr spärlich.
Sie haben eine Methode, die einen Benutzer erstellt oder eine Aufgabe ausführt. Wenn Sie 50 Benutzer erstellen möchten, können Sie es einfach 50 Mal aufrufen. Wenn Sie sich für diese Methode als API entscheiden, kann Ihr lokaler Webserver Named-Pipes-Verbindungen herstellen, und das ist kein Problem - Ihr Desktop-Client kann auch darauf zugreifen, aber bei der Erstellung eines Massenbenutzers wird die API plötzlich 50-mal über das Internet gehämmert, was nicht der Fall ist nicht gut Sie müssen also eine Massenmethode erstellen, aber eigentlich erstellen Sie sie nur für Desktop-Clients. Auf diese Weise müssen Sie am Ende a) Ihre API basierend auf der Integration ändern und können nicht einfach direkt in sie integrieren. B) Sie müssen viel mehr Arbeit leisten, um eine zusätzliche Funktion zu erstellen.
YAGNI . Wenn Sie nicht speziell vorhaben, zwei identisch funktionierende Anwendungen, beispielsweise eine Web- und eine Windows-Anwendung, zu schreiben, ist dies eine enorme Menge zusätzlicher Entwicklungsarbeit.
Das Debuggen ist viel schwieriger, wenn Sie nicht durchgängig arbeiten können.
Viele unabhängige Vorgänge, die viel Hin und Her erfordern, z. B. Code, der möglicherweise den aktuellen Benutzer abruft, überprüft, ob der Benutzer die Administratorrolle innehat, die Firma abruft, der der Benutzer angehört, eine Liste anderer Mitglieder abruft und alle sendet eine E-Mail. Das würde eine Menge API-Aufrufe erfordern oder das Schreiben einer maßgeschneiderten Methode für die gewünschte Aufgabe, wobei der einzige Vorteil dieser maßgeschneiderten Methode die Geschwindigkeit und der Nachteil wäre, dass sie unflexibel wäre.
Wahrscheinlich noch ein paar Gründe, die mir auf den Kopf gefallen sind.
Mir kommt es nur so vor, als würde es sich nicht lohnen, wenn Sie wirklich zwei identische Anwendungen benötigen. Ich habe noch nie eine ASP.NET-Anwendung gesehen, die so erstellt wurde. Sie müssten zwei separate Anwendungen (die API und Ihren Code) schreiben und beide auch versionieren (wenn Ihre Benutzerseite ein neues Feld erhält, müssen Sie d müssen die API und Ihren konsumierenden Code gleichzeitig aktualisieren, um keine negativen Auswirkungen zu haben, oder viel zusätzliche Arbeit in die Aufrechterhaltung der Robustheit investieren).
Edit: Einige großartige Antworten, die wirklich anfangen, eine gute Vorstellung davon zu bekommen, was dies alles jetzt bedeutet. Um meine Frage zu erweitern: Wie würden Sie eine MVC-App strukturieren, um dieser API-Struktur zu folgen?
Sie haben beispielsweise eine Website, auf der Informationen zu einem Benutzer angezeigt werden. Unter MVC haben Sie:
View - (CS) HTML-Seite, auf der ein UserViewModel-Controller angezeigt wird - Ruft GetUser () auf und erstellt ein UserViewModel, das an die View Manager-Klasse (Art Ihrer API) mit einer GetUser-Methode übergeben wird.
Der Controller führt GetUser () aus, aber Sie möchten auch eine Desktop-App. Dies bedeutet, dass Ihr GetUser über eine API verfügbar gemacht werden muss. Möglicherweise möchten Sie eine TCP-Verbindung, entweder WCF oder Remoting. Sie möchten auch eine mobile App, die RESTful ist, da dauerhafte Verbindungen schuppig sind.
Würden Sie dann für jeden eine API schreiben, einen WCF-Webdienst, der über eine Methode GetUser () verfügt und der nur den Code enthält return new UserManager().GetUser()
? Und eine MVC 4 Web-API-Methode, die das Gleiche tut? Rufen Sie GetUser weiterhin direkt in Ihrer MVC-Controller-Methode auf?
Oder würden Sie die Lösung auswählen, die für alle drei geeignet ist (Web-API-REST-Service) und alles darauf aufbauen, sodass alle drei Apps API-Aufrufe (die MVC-Aufrufe, an den lokalen Computer) ausführen.
Und ist das nur ein theoretisch perfektes Szenario? Ich sehe große Gemeinkosten bei der Entwicklung auf diese Weise, insbesondere wenn Sie sich auf eine Weise entwickeln müssen, die es Ihnen ermöglicht, Operationen auf eine REST-artige Weise durchzuführen. Ich denke, ein Teil davon wurde in den Antworten behandelt.
Edit 2: Nachdem ich mehr gelesen habe, habe ich unten einen Kommentar eingefügt, der meiner Meinung nach das erklären könnte. Die Frage ist ein Trick, denke ich. Wenn Sie Ihr Back-End als API schreiben, war ich verwirrt, dass es einen einzigen Webservice geben sollte, den alle Aufrufe (MVC-App, Desktop-App, mobile App) erledigen.
Ich bin zu dem Schluss gekommen, dass Sie wirklich sicherstellen sollten, dass Ihre Geschäftslogikschicht korrekt entkoppelt ist. Wenn ich mir meinen Code anschaue, mache ich das bereits - der Controller ruft GetUser()
einen Manager auf und erstellt daraus ein Ansichtsmodell, um es mit einer Ansicht zu rendern. Die Geschäftslogikschicht ist also eine API. Wenn Sie es jedoch von einer Desktop-App aus aufrufen möchten, müssen Sie so etwas wie einen WCF-Dienst schreiben, um das Aufrufen zu erleichtern. Es reicht schon aus, eine WCF-Methode aufzurufen GetUser()
, die den Code enthält return MyBusinessLayer.GetUser()
. Die API ist also die Geschäftslogik, und WCF- / Web-APIs usw. sind nur ein bisschen Code, damit externe Anwendungen sie aufrufen können.
Es ist also mit einem gewissen Aufwand verbunden, dass Sie Ihre Geschäftslogikschicht je nach Bedarf in verschiedene APIs einbinden müssen und für jeden Vorgang, den Ihre anderen Apps ausführen sollen, eine API-Methode schreiben müssen Suchen Sie nach einer Möglichkeit zur Authentifizierung, aber im Großen und Ganzen ist es das Gleiche. Stecken Sie Ihre Geschäftslogik in ein separates Projekt (Klassenbibliothek), und Sie werden wahrscheinlich kein Problem haben!
Hoffentlich ist diese Interpretation richtig. Vielen Dank für alle Diskussionen / Kommentare, die es generiert hat.