Czy powinniśmy wywoływać interfejs API sieci Web z aplikacji MVC w tym samym rozwiązaniu?

33

Pracuję nad projektem w MVC, który ma aplikację mobilną, więc jedno jest jasne, że musimy użyć interfejsu API sieci Web, aby można go było używać w aplikacji mobilnej.

Po utworzeniu interfejsu API, gdy zaczęliśmy opracowywać witrynę sieci Web, jesteśmy zdezorientowani i rozmawialiśmy o tym, czy użyć interfejsu API, czy bezpośrednio uzyskać dostęp do obiektu biznesowego. Skończyło się na tym, że mieliśmy bardziej doświadczonego programistę opiniotwórczego do korzystania z interfejsu API sieci Web zamiast bezpośredniego używania obiektu biznesowego.

Mam wątpliwości co do tej struktury rozwiązania.

1) Dlaczego powinniśmy korzystać z interfejsu API sieci Web i składać żądania HTTP (co jest czasochłonne), aby uzyskać lub umieścić dane zamiast obiektu biznesowego bezpośrednio w tym samym rozwiązaniu.

2) Po argumentach powiedzieli, co jeśli klient chce hostować API i Internet na innym serwerze w chmurze i stosować skalowanie tylko na API lub może chcieć mieć inny adres URL do uzyskiwania dostępu do API i Web (co jest logiczne). Czy w takim przypadku powinniśmy wywołać Web API z aplikacji MVC w tym samym rozwiązaniu?

3) Jeśli hostujemy API i Internet na innym hostingu, oznacza to, że nasza Sieć będzie używać WebClient i będzie nawiązywać połączenia HTTP na każdej nawigacji. Czy to jest poprawne?

4) Jeśli obiekt biznesowy zostanie utworzony zarówno z interfejsu API, jak i hostingu na innym serwerze, to jeśli coś zmieni się w BL, będzie trzeba zaktualizować kompilację na obu serwerach.

5) Lub powinniśmy stworzyć tylko jeden projekt dla API i możemy dodawać widoki lub strony HTML w celu opracowania interfejsu WWW, aby w ten sposób można było wywoływać API bezpośrednio z ajax.

Zgodnie z moją wiedzą # 5 jest najlepszym rozwiązaniem lub API służy tylko do dostępu stron trzecich. Jeśli mamy DB, EF, warstwę danych i warstwę biznesową w tym samym rozwiązaniu, nie powinniśmy używać interfejsu API do wykonywania połączeń HTTP i bezpośredniego dostępu do obiektu biznesowego. (popraw mnie, jeśli się mylę) API jest potrzebne, gdy aplikacja mobilna lub komputer stacjonarny lub ktoś chce uzyskać dostęp do aplikacji, abyśmy mogli mieć to samo repozytorium i warstwę danych.

W moim scenariuszu muszę utworzyć interfejs API, ponieważ mamy również aplikację mobilną, a po stronie interfejsu API projektu nazwaliśmy warstwę biznesową (oddzielny projekt), a warstwa biznesowa komunikuje się z warstwą dostępu do danych (oddzielny projekt). Więc moje pytanie brzmi: czy hostujemy nasz interfejs API i sieć na różnych serwerach, wówczas wywołanie interfejsu API będącego żądaniem HTTP może potrwać dłużej niż używanie metody z warstwy biznesowej podczas tworzenia projektu i mamy .dll warstwy biznesowej. W kontrolerze API po prostu przekształcamy put naszej firmy na format json.

Szukałem w Internecie, ale nie uzyskałem przekonującej odpowiedzi. Znalazłem blog http://odetocode.com/blogs/scott/archive/2013/07/01/on-the-coexistence-of-asp-net-mvc-and-webapi.aspx omawiający ten sam punkt, ale znowu na tym blogu mam pytanie, dlaczego musimy rozważyć scenariusz nr 3?

Aktualizacja: Możemy mieć inny projekt API i projekt MVC i możemy wywoływać API z sieci za pomocą jvascript lub możemy użyć wzorca MVVM.

Ruchir Shah
źródło
MVVM czy MVC z widokami modeli?
Andrew Hoffman
Używamy MVC
Ruchir Shah,
Ok, więc naprawdę nie ma poprawnej odpowiedzi. Wywoływanie interfejsu API jest korzystne tylko w przypadku poprawy jego jakości. (zjadanie własnej karmy dla psów) Wykonywanie połączeń Inproc zamiast dzwonienia za pośrednictwem usług ma także zalety związane z wydajnością.
Andrew Hoffman
Google raz przejrzał to pytanie. Ich produkty to zarówno usługi, jak i strony internetowe. Uważam, że zdecydowali się na korzystanie z własnych stron internetowych.
Andrew Hoffman
2
Tak. programmers.stackexchange.com/questions/148556/... i stackoverflow.com/questions/3590561/... to dobre zasoby. Niektórzy tak robią, inni nie. Nie ma prawdziwego „poprawnego” sposobu.
Andrew Hoffman,

Odpowiedzi:

37

Świetne pytanie! Zawsze szukam lepszego sposobu ustrukturyzowania moich projektów. Każdy podniesiony przez ciebie punkt ma swoje zalety i po zbadaniu różnych struktur rozwiązań muszę powiedzieć, że zgadzam się z większością komentarzy tutaj: nie ma idealnego rozwiązania. Kilka pytań, które należy sobie zadać w obliczu tego rodzaju problemu: jak złożona jest ta aplikacja? Z iloma systemami będę musiał zintegrować - lub ile systemów będzie wymagało integracji z tym systemem? Ile testów planuję zrobić? Czy istnieje osobny zespół ds. Projektowania / interfejsu użytkownika? Czy będziemy musieli skalować? Co stanowi sesję?

Spójrzmy na kilka scenariuszy i sposoby wykorzystania odrobiny sprytnej inżynierii, aby wszystko naprawdę wybuchło (i kilka sztuczek, aby uczynić to trochę łatwiejszym).

Hostowanie zarówno interfejsu API, jak i strony internetowej w tym samym projekcie
W tym przypadku możesz mieć jedno rozwiązanie z zerową lub większą liczbą projektów warstwy biznesowej i pojedynczym hybrydowym projektem MVC / WebAPI (a także innymi projektami - narzędziowymi itp.).

Pro's
Wszystko jest w jednym miejscu. Nie musisz klaksonować w skomplikowanych wiadomościach (połączenia HttpClient), możesz mieć stan wspólnej sesji (klient i serwer za pomocą plików cookie, sesja InProc / OutOfProc itp.), Pula połączeń, wspólna logika itp. Wdrożenie nie może być prostsze.

Con's
Everything jest w jednym miejscu .. To prawdopodobnie najbardziej monolityczna możliwa struktura. Nie ma jasno zdefiniowanych interfejsów między twoimi warstwami. Skończysz z wysoką spójnością . Leniwi programiści unikają interfejsów podczas pracy z tego rodzaju architekturą, co sprawia, że ​​testowanie jest ogromnym problemem. Skalowanie / kolokacja aplikacji będzie trudne.

Używałbym
tej struktury projektu do jednorazowej, wewnętrznej lub prostej aplikacji. Budujesz szybki system śledzenia rejestracji do obozu koszykówki w lokalnym Y? To twoja architektura!

WebAPI i strona internetowa w różnych projektach
Wolę ten przypadek. Masz jedno rozwiązanie z jednym (lub więcej) projektami MVC i jednym projektem WebAPI.


Modularyzacja Pro ! Luźne powiązanie! Każdy projekt może być samodzielny, testowany osobno i może być zarządzany inaczej. Umożliwia to łatwiejsze wdrażanie różnych strategii buforowania w zależności od potrzeb. Utrzymując stałe granice między różnymi systemami, możesz łatwiej zawierać umowy, które pozwalają egzekwować określone wzorce użytkowania i ograniczać potencjalne tarcie (czytaj: mniej błędów przy mniejszej możliwości nadużywania API). Skalowanie jest nieco łatwiejsze, ponieważ wystarczy skalować tylko te bity, które widzą duże obciążenie. Integracja staje się również nieco łatwiejsza w obsłudze, ponieważ będziesz musiał mieć pojęcie o tym, jak będzie wyglądał Twój interfejs API od samego początku.


Konserwacja Con jest nieco trudniejsza. Wiele projektów oznacza, że ​​będziesz potrzebować właścicieli projektów / funkcji, aby śledzić fuzje, kontrakty (interfejsy), wdrożenia itp. Utrzymanie kodu, dług techniczny , śledzenie błędów, zarządzanie stanem - wszystkie stają się problemami, ponieważ mogą wymagać implementacji w różny sposób na twoje potrzeby. Tego rodzaju aplikacje również wymagają największego planowania i kuracji w miarę ich wzrostu.

Używa
budowania aplikacji, która mogłaby dziś mieć 100 użytkowników i 100 000 w przyszłym tygodniu / miesiącu? Czy aplikacja musi wysyłać powiadomienia, zarządzać złożonymi przepływami pracy i mieć wiele interfejsów (web + aplikacja mobilna + SharePoint)? Masz dużo czasu i uwielbiasz rozwiązywać ponad 5000 łamigłówek w weekend? To jest architektura dla Ciebie!

Wskazówki
Po nakreśleniu powyższego rozumiem, jak twój następny projekt może wyglądać nieco zniechęcająco. Nie martw się, oto kilka sztuczek, których nauczyłem się przez lata.

  1. Spróbuj użyć sesji bezstanowych. W mniejszych systemach może to oznaczać przechowywanie zaszyfrowanego pliku cookie zawierającego przynajmniej wewnętrzny identyfikator bieżącego użytkownika i limit czasu. Większe systemy mogą oznaczać przechowywanie zaszyfrowanego pliku cookie z prostym identyfikatorem sesji, który można pobrać z magazynu danych (redis, pamięć tabel, DHT itp.). Jeśli możesz przechowywać wystarczającą ilość informacji, abyś nie musiał trafić do głównej bazy danych na każde żądanie będziesz w dobrym miejscu - ale staraj się, aby pliki cookie nie przekraczały 1k.
  2. Pamiętaj, że prawdopodobnie będzie więcej niż jeden model. Spróbuj myśleć w kategoriach modeli i rzutów (linki, które tu znalazłem były… nie dobre… myśl: pozycja inwentarza jednego człowieka jest pozycją zamówienia innego mężczyzny - ta sama podstawowa struktura, ale różne widoki). Niektóre projekty mają inny model dla każdej granicy logicznej / konceptualnej (tj. Wykorzystują konkretny model do komunikacji z określonym API.
  3. API's Everywhere! Za każdym razem, gdy obiekt / klasa / struktura ujawnia jakiekolwiek dane lub zachowanie, ustanawiasz API. Należy pamiętać, w jaki sposób inne podmioty lub zależności będą korzystać z tego interfejsu API. Zastanów się, jak możesz przetestować ten interfejs API. Zastanów się, co może mówić do tego API (inne obiekty za pomocą kodu? Inne systemy za pomocą protokołu?) I jak te dane są ujawniane (silnie typowane? JSON? * Kaszel * XML?).
  4. Zbuduj to, co masz, a nie to, co sobie wyobrażasz, że będziesz miał za dwa lata. Inna odpowiedź odwołuje się do YAGNI - są absolutnie poprawne! Rozwiązanie wyobrażonych problemów sprawia, że ​​termin jest wyobrażony. Ustal solidne cele dla swoich iteracji i osiągnij je. Rozmieścić! Projekt w fazie rozwoju to projekt z tylko jednym użytkownikiem - ty!
  5. YMMV (Twój przebieg może się różnić ). Jest tylko jeden absolut: tutaj jest problem, budujesz rozwiązanie. Cała reszta jest całkowicie w powietrzu. Oba powyższe rozwiązania mogą odnieść ogromny sukces - i porażkę ssania. Wszystko zależy od Ciebie, Twoich narzędzi i sposobu ich użycia. Lekko stąpaj, kolego dewelopera!
Bobby D.
źródło
2
Świetna odpowiedź! Chciałbym móc nagrodzić cię za twoje pisanie, ale skoro nie mogę o niczym myśleć, po prostu podążę za tobą na Twitterze. : P
Dan
„mocno wpisany? JSON? * kaszel * XML” czego brakuje?
Alexander Derck
1
@AlexanderDerck Wspominam o trzech różnych opcjach formatowania (choć jest ich więcej) .. „żart” polega na tym, że XML może być trudny w obsłudze i często może dodać sporo narzutu (serializacja / deserializacja). Nie oznacza to, że czasami nie ma takiej potrzeby (szczególnie podczas pracy z grupami zewnętrznymi) ..
Bobby D
6

Bezpośredni dostęp do obiektów biznesowych bezpośrednio (zakładam, że masz na myśli kontroler) będzie szybszy i łatwiejszy.

co jeśli klient chce hostować interfejs API i sieć na innym serwerze w chmurze i stosować skalowanie tylko w interfejsie API lub może chcieć mieć inny adres URL w celu uzyskania dostępu do interfejsu API i sieci (co jest nieco logiczne)

Następnie musisz hostować je osobno ... ale to nie brzmi dla mnie zbyt logicznie, na pewno chciałbyś skalować oba. Czy na pewno musisz spełnić ten wymóg? To brzmi jak przesada. Pamiętaj o YAGNI - jeśli go nie potrzebujesz, nie buduj go. Kiedy go potrzebujesz, zbuduj go.

Jeśli to ja zbudowałbym witrynę przy użyciu technologii, która najlepiej pasuje do witryny, to kiedy (jeśli) potrzebujesz usługi, którą inni mogą nazwać, zbuduj ją osobno.

Rocklan
źródło
Całkowicie się z tobą zgadzam, ponieważ pod koniec dni skalowanie jest ważne, a podział troski ma dla mnie znaczenie. Zawsze dobrze jest myśleć o budowaniu architektury n-tier w związku ze zmianami technologii, które można łatwo aktualizować lub utrzymywać. Na przykład owijanie pojemnikiem dokującym to kolejna rzecz do rozważenia w przyszłości.
Ishwor Khanal,
4

Powiedziałbym; wolą MVC wywołujące WebAPI przez HTTPClient. Przytłaczająca jest logika „core dll”, ale główną zaletą jest to, że cały system będzie miał dostęp do obiektów domeny na HTTP za pośrednictwem jednego punktu ... W każdym razie… z odbieraniem architektury Micro Service ORAZ aplikacjami już przełączającymi się na Frameworki po stronie klienta (AngularJS itp.) .... lepiej traktuj MVC jako kolejnego klienta ... i ucz swojego zespołu, aby dobrze zarządzał interfejsami API ...

UTRZYMUJ TO SIMPE. Mam nadzieję, że to pomoże. Dzięki..

Manoj Kumar Bisht
źródło
Nie jestem pewien, dlaczego zostało to przegłosowane, ale jest to najlepsza odpowiedź na dobrą architekturę imo
weagle08
Zastanawiałem się nad sytuacją, w której pomyślałem, że dobrym pomysłem jest wywoływanie API z własnej aplikacji MVC, ale myślę, że różni się od tego i być może wielu innych pytań, które odnoszą się do tego wywołania z logiki serwera. W moim przypadku będę wywoływał to z moich widoków, w których Vue tworzy złożone interfejsy użytkownika i przekazuje dane do tego interfejsu API. Potem zdałem sobie sprawę, że jest to uzasadnione, ponieważ w moim przypadku jest to wywoływanie z widoku vs. elementy po stronie serwera, a wszelkie połączenia HTTP byłyby i tak wykonywane przy rozważaniu dowolnego interfejsu użytkownika - może nawet bardziej, jeśli widoki wykonane przez ASP. Ale działa tylko w środowiskach JS.
Vasily Hall
Zobacz wywoływanie interfejsu API bezpośrednio jest dobrym pomysłem .... ale widoki MVC są generowane z serwera, więc możesz również przetwarzać dane z serwera, szczególnie to jest bardziej odpowiednie do przetwarzania na serwerze) przed renderowaniem widoków częściowych (widoki) ... Framework RESS (RESS : Responsywne projektowanie stron internetowych + komponenty po stronie serwera) .... ALE NAJLEPSZE KORZYSTANIE Z PURE Frameworks klienta (Angular / ReactJS), jeśli możesz całkowicie uniknąć MVC ...
Manoj Kumar Bisht