Budujemy architekturę Microservice dla naszych projektów, głównie aplikacje frontowe Symfony współpracują z wewnętrznymi interfejsami API RESTful.
Problem polega na tym, że podejście to łamie zarządzanie jednostkami Symfony polegającymi w dużej mierze na Doctrine z bazą danych. Tam, gdzie Symfony zwykle obsługuje jednostki za pomocą Doctrine, automatyzując większość pracy, nie można tego łatwo odtworzyć, gdy musimy uzyskać dostęp do danych zewnętrznych z interfejsów API.
Na przykład z jednostką klienta:
- Korzystając z Doctrine, musimy po prostu zdefiniować naszą klasę klienta, a teraz można łatwo tworzyć, aktualizować i odzyskiwać naszych klientów
- Dzięki zastosowaniu interfejsu API REST klienci są dostępni za pośrednictwem interfejsu API, ale mamy wiele pracy, aby zdefiniować sposób tworzenia klienta (POST), aktualizowania (PUT), pobierania (GET) itp.
Należy zauważyć, że klienci używają kilku aplikacji, nie tylko aplikacji front-end, stąd dedykowany interfejs API.
Czy powinniśmy tworzyć klasy z metodami podobnymi do bytu, ukrywającymi złożoność wywołań API, importując wszystkie dane API lokalnie i uzyskując do nich dostęp za pośrednictwem Doctrine lub w inny sposób?
Odpowiedzi:
Zrobiłem projekt oparty na symfony, który używa zewnętrznego API (JSON); to, co zrobiłem, to stworzenie niezależnej biblioteki klienta („biblioteka klienta” - oprogramowanie, pakiet kompozytora), z własnym zestawem jednostek (POPO); integruje się ze strukturą za pomocą interfejsów dostarczanych przez Symfony (na przykład, po prostu tworząc niestandardowego dostawcę użytkownika ).
Klient wykonuje połączenia HTTP „za kulisami” - jest to ważne dla przyszłych możliwości testowania. Nie chcesz ujawniać sposobu komunikacji ze źródłem danych, a także nie chcesz, aby testy opierały się na interfejsie API na żywo.
Interfejs biblioteki klienta (przykład jak może to wyglądać):
Biblioteka klienta wewnętrznie używa Guzzle do komunikacji i komponentu Doctrine Cache do buforowania wyników. Odwzorowanie między obiektami encji a Jsonem zostało wykonane przez twórców mapowania, którzy raz napisali - nie zmieniali się bardzo często (ani wcale zdarzeń). W takim przypadku sugerowałbym użycie JMS Serializer do automatycznej transformacji do i z JSON (zakładam, że używasz JSON).
Będziesz potrzebował dobrego mechanizmu buforowania i lokalnego magazynu, takiego jak Redis. Wykonywanie api-połączeń przy każdym żądaniu aplikacji zabije serwer i drastycznie spowolni aplikację. Bardzo ważne jest, aby zrozumieć, jak działają pamięci podręczne http. Jeśli twój interfejs API nie używa buforujących nagłówków (lub używa go w niejasny sposób), śledzenie zmian będzie bardzo trudne i pochłania zasoby.
Zastanów się także, jak powinien zachowywać się klient, jeśli połączenie zostanie zerwane - czy klient powinien użyć zablokowanych danych? Dobrym pomysłem byłoby użycie serwera proxy między aplikacją a interfejsem API. W takim przypadku serwer proxy (np. Varnish) może przyspieszyć żądania, a także odświeżyć zablokowane dane w tle bez spowalniania aplikacji. Utrzyma również twoją stronę internetową w przypadku awarii interfejsu API. W międzyczasie możesz nie być w stanie zapisywać danych, ale użytkownicy nadal będą mogli przeglądać dane w pamięci podręcznej.
Mówiąc o doktrynie, patrz „ Prawo instrumentu ”.
źródło
Doctrine to warstwa dostępu do bazy danych. Nie chcesz uzyskać dostępu do bazy danych, ale apis. Nadal możesz utworzyć Encję, ale potem jako prosty obiekt, który nie musi nic rozszerzać naszej implementacji (popo). Powinien mieć repozytorium, które implementuje wszystkie metody CRUD. W takim przypadku wywołania interfejsu API zamiast bazy danych. Stworzyłbym do tego interfejs. Aplikacja nie musi wyglądać inaczej, z wyjątkiem tego, że musisz wziąć pod uwagę wszędzie tam, gdzie mikro usługa może nie odpowiedzieć.
źródło
Do Twojej dyspozycji jest teraz komponent HttpClient dla v4.3.
https://symfony.com/blog/new-in-symfony-4-3-httpclient-component
źródło