Dzisiaj miałem gorącą dyskusję na temat naszej aplikacji MVC. Mamy stronę internetową napisaną w MVC ( ASP.NET ) i zwykle jest zgodna ze schematem robienia czegoś w widoku -> uderz w kontroler -> kontroler buduje model (wywołuje menedżera, który pobiera dane, buduje model w sama metoda kontrolera) -> model przechodzi do widoku -> spłucz i powtórz.
Powiedział, że nasz kod jest zbyt ściśle powiązany. Na przykład, jeśli chcielibyśmy mieć również aplikację komputerową, nie moglibyśmy użyć naszego istniejącego kodu.
Rozwiązaniem i najlepszą praktyką, którą powiedział, jest zbudowanie interfejsu API, a następnie zbudowanie strony internetowej na podstawie interfejsu API, a następnie zbudowanie aplikacji komputerowej, aplikacji mobilnej itp. Jest bardzo proste.
Z różnych powodów wydaje mi się to złym pomysłem.
W każdym razie nie wydaje mi się, że mogę znaleźć coś w Google, co mogłoby omówić tę praktykę. Czy ktoś ma jakieś informacje o zaletach, wadach, dlaczego warto, dlaczego nie lub dalszej lektury?
Niektóre powody uważam za zły pomysł:
To zbyt abstrakcyjne, żeby uruchomić backend z API. Próbujesz uczynić go zbyt elastycznym, co sprawi, że będzie to niemożliwy do zarządzania bałagan.
Wszystkie rzeczy wbudowane w MVC wydają się bezużyteczne, takie jak role i uwierzytelnianie. Na przykład atrybuty i bezpieczeństwo [Autoryzuj]; będziesz musiał rzucić własne.
Wszystkie wywołania interfejsu API będą wymagać dołączenia informacji o bezpieczeństwie, a będziesz musiał opracować system tokenów i tak dalej.
Będziesz musiał napisać pełne wywołania API dla każdej funkcji, jaką Twój program kiedykolwiek wykona. Prawie każda metoda, którą chcesz wdrożyć, będzie wymagała uruchomienia interfejsu API. Pobierz / zaktualizuj / usuń dla każdego użytkownika oraz wariant dla każdej innej operacji, np. Zaktualizuj nazwę użytkownika, dodaj użytkownika do grupy itp. Itd., A każda z nich będzie odrębnym wywołaniem API.
Tracisz wszelkiego rodzaju narzędzia, takie jak interfejsy i klasy abstrakcyjne, jeśli chodzi o interfejsy API. Rzeczy takie jak WCF mają bardzo słabe wsparcie dla interfejsów.
Masz metodę, która tworzy użytkownika lub wykonuje jakieś zadanie. Jeśli chcesz utworzyć 50 użytkowników, możesz po prostu zadzwonić do niego 50 razy. Gdy zdecydujesz się zastosować tę metodę jako interfejs API, lokalny serwer może połączyć się z nią nazwanymi potokami i nie ma problemu - twój klient pulpitu też może go trafić, ale nagle twoje masowe tworzenie użytkowników będzie wymagało 50-krotnego udoskonalenia interfejsu API nieźle. Musisz więc stworzyć metodę zbiorczą, ale tak naprawdę tworzysz ją tylko dla klientów stacjonarnych. W ten sposób musisz a) zmodyfikować interfejs API w oparciu o to, co się z nim integruje, i nie możesz po prostu bezpośrednio z nim zintegrować, b) wykonać o wiele więcej pracy, aby utworzyć dodatkową funkcję.
YAGNI . O ile nie planujesz specjalnie napisać dwóch identycznie działających aplikacji, na przykład jednej aplikacji internetowej i jednej aplikacji Windows, jest to ogromna ilość dodatkowych prac programistycznych.
Debugowanie jest znacznie trudniejsze, gdy nie można przejść od końca do końca.
Wiele niezależnych operacji, które będą wymagały wielu ruchów w przód iw tył, na przykład jakiś kod może uzyskać bieżącego użytkownika, sprawdzić, czy użytkownik jest w roli administratora, uzyskać firmę, do której należy użytkownik, uzyskać listę innych członków, wysłać im wszystkich email. Wymagałoby to wielu wywołań interfejsu API lub napisania niestandardowej metody dla konkretnego zadania, które chcesz, a jedyną korzyścią tej metody byłaby szybkość, ale wadą byłoby to, że byłaby nieelastyczna.
Prawdopodobnie kilka innych powodów, które są po prostu z mojej głowy.
Wydaje mi się, że chyba, że naprawdę potrzebujesz dwóch identycznych aplikacji, to naprawdę nie jest tego warte. Nigdy nie widziałem aplikacji ASP.NET zbudowanej w ten sposób, musisz napisać dwie osobne aplikacje (interfejs API i kod) i kontrolować je również w obu wersjach (jeśli strona użytkownika otrzyma nowe pole, „ d muszę jednocześnie zaktualizować interfejs API i kod używający, aby zapewnić brak negatywnych efektów lub włożyć dużo dodatkowej pracy w utrzymanie jego niezawodności).
Edycja: Kilka świetnych odpowiedzi, naprawdę zaczynam rozumieć, co to wszystko znaczy teraz. Więc, aby rozwinąć moje pytanie, w jaki sposób stworzyłbyś aplikację MVC pod kątem tej struktury API?
Na przykład masz witrynę internetową, która wyświetla informacje o użytkowniku. W ramach MVC masz:
Widok - (CS) strona HTML, która wyświetla kontroler UserViewModel - Wywołuje GetUser () i tworzy UserViewModel, który przekazuje do klasy menedżera widoku (rodzaj interfejsu API), który ma metodę GetUser.
Kontroler obsługuje GetUser (), ale chcesz też aplikację komputerową. Oznacza to, że Twój GetUser musi zostać ujawniony za pośrednictwem pewnego rodzaju interfejsu API. Możesz chcieć mieć połączenie TCP, WCF lub być może zdalne. Potrzebujesz także aplikacji mobilnej, która będzie RESTful, ponieważ trwałe połączenia są niestabilne.
Czy napisałbyś zatem API dla każdego z nich, usługę internetową WCF, która ma metodę GetUser () i tylko kod return new UserManager().GetUser()
? I metoda web api mvc 4, która robi to samo? Nadal wywołujesz GetUser bezpośrednio w metodzie kontrolera MVC?
Czy też wybrałbyś rozwiązanie, które działałoby dla wszystkich trzech (usługa REST interfejsu API sieci Web) i zbudowałbyś na nim wszystko, więc wszystkie trzy aplikacje wykonują wywołania API (te mvc, na maszynę lokalną).
A czy to tylko teoretyczny idealny scenariusz? Widzę duże koszty ogólne w rozwoju w ten sposób, szczególnie jeśli musisz się rozwijać w sposób, który pozwoli ci wykonywać operacje w sposób RESTful. Myślę, że niektóre z nich zostały ujęte w odpowiedziach.
Edycja 2: Po przeczytaniu większej ilości rzeczy umieściłem poniżej komentarz, który moim zdaniem może to wyjaśnić. To pytanie jest podchwytliwe. Jeśli napiszesz back-end jako API, pomyliłem myśl, że powinna istnieć jedna usługa internetowa, do której wszystko (aplikacja mvc, aplikacja na komputer, aplikacja mobilna) wzywa.
Doszedłem do wniosku, że tak naprawdę powinieneś upewnić się, że twoja warstwa logiki biznesowej jest prawidłowo oddzielona. Patrząc na mój kod, robię to już - kontroler zadzwoni GetUser()
do menedżera, a następnie utworzy z niego model widoku do renderowania za pomocą widoku. Tak naprawdę warstwa logiki biznesowej jest interfejsem API. Jeśli chcesz zadzwonić z aplikacji komputerowej, musisz napisać coś w rodzaju usługi WCF, aby ułatwić jej wywołanie. Wystarczy nawet wywołać metodę WCF GetUser()
zawierającą kod return MyBusinessLayer.GetUser()
. API jest więc logiką biznesową, a API WCF / web itp. To po prostu fragmenty kodu, które pozwalają aplikacjom zewnętrznym na wywołanie go.
Jest więc pewien narzut, polegający na tym, że musisz zawinąć warstwę logiki biznesowej w różne interfejsy API w zależności od tego, czego potrzebujesz, i będziesz musiał napisać metodę API dla każdej operacji, którą chcesz wykonać w innych aplikacjach, a ponadto będziesz musiał wymyślić sposób przeprowadzenia uwierzytelnienia, ale w większości jest taki sam. Trzymaj logikę biznesową w osobnym projekcie (bibliotece klas), a prawdopodobnie nie będziesz mieć problemu!
Mam nadzieję, że ta interpretacja jest poprawna. Dziękujemy za całą wygenerowaną dyskusję / komentarze.