Kilka generycznych API czy jedno konkretne?

Kilka generycznych API czy jedno konkretne?
AP
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 169
0

Mam standardowa aplikację webową, REST API wystawione z backendu i konsumowane przez frontend. Może warto to zaznaczyć, jedyne przeznaczenie tego API to serwowanie danych na ten frontend, nie ma być ono projektowane tak by było używane przez inne aplikacje.
No i powiedzmy, że mam 3 główne moduły w aplikacji - user, order i product, każdy z nich to prosty CRUD, w bazie danych to 3 osobne tabelki, generalnie API wygląda mniej więcej tak, danych oczywiście jest dużo więcej w realnym API.

Kopiuj
 GET /user/{id}
  {
    "id": "user123",
    "email" : "johndoe@gmail.com",
    "firstName" : "john",
    "lastName" : "doe",
    "city": "new york"
  },
  GET /product/{id}
  {
    "id": "product123",
    "name": "carpenter's hammer",
    "photoUrl": "http://hammerphoto.pl"
    "price": {
      "amount": 15,
      "currency": "USD"
    },
    "stock": 75
  }
  GET /order/{id}, 
  GET /order?orderedBy=user123
  {
    "id" : "order123",
    "orderedProduct": "product123",
    "orderedBy" : "user123",
    "orderedAt": "2020-11-23T10:00:00"
  }

No i można sobie łatwo wyobrazić użycie każdego z tych endpointów, no ale dochodzi teraz wymaganie by zrobić profil użytkownika, a na nim wyświetlić:

  • dane osobowe użytkownika
  • ostatnie zamówienia użytkownika
  • ostatnio kupione produkty

Teoretycznie mogę w tym celu zawołać wymienione 3 wyżej endpointy, ale

  • nazwę i zdjęcie młotka i innych przedmiotów pobiorę z GET /product/{id} dopiero jak dostanę odpowiedź z GET/order?orderedBy
  • prawie każda usługa zwróci dane których nie potrzebuje w tym przypadku, np. pobierając przedmioty kupione przez użytkownika nie potrzebuje informacji o tym ile danych przedmiotow jest jeszcze na stanie w sklepie, cena też mnie teraz średnio interesuje

Zaznaczam jeszcze raz, to wyżej to uproszczona wersja problemu, faktycznie takich punktów gdzie np. nie potrzebuje wszystkich danych, albo potrzebuje zebrać wyniki 2-3 API jest więcej. W każdym razie, jak to zaimplementować?

  • podejście opisane wyżej jest mimo wszystko ok
  • jedno zbiórcze API, ktore pod spodem zawoła kilka serwisów i zagreguje mi to co potrzebuje
  • trzy uproszczone wersje API powyżej, np.
Kopiuj
  GET /product/simplified/{id}
  {
    "name": "carpenter's hammer",
    "photoUrl" : "http.."
  }
  • GraphQL
Shalom
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Space: the final frontier
  • Postów: 26433
3

faktycznie takich punktów gdzie np. nie potrzebuje wszystkich danych, albo potrzebuje zebrać wyniki 2-3 API jest więcej

GraphQL. To jest taki sztandarowy przykład sytuacji kiedy to ma sens.

AreQrm
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Londyn
  • Postów: 873
1

Skoro to prosty CRUD, nie jakieś mikroserwisy itp, i do tego Ty piszesz API dla frontu, nie dla 'świata' to zrobiłbym to prosto (przy innej architektórze aplikacji, można i często nawet powinno się to zrobić inaczej, tak samo jak API to coś co traktujesz osobno i np sprzedajesz kilku klientom, a każdy sobie woła jak chce). Czyli tam gdzie potrzebujesz konkretnych danych, wystawiłbym konkretny endpoint. Czy jeden czy kilka, to zależy. To podejście oczywiście wiąze Ci API z frontem, zmieniasz jedno musisz zmienić drugie... Ale skoro kontrolujesz oba... to raczej nie jest to problem.

Jedno czy kilka?
Np weżmy ten profil.

  1. Na frontendzie możesz mieć jeden komponent do wyświetlenia i możesz chcieć zrobić tylko jeden call do backendu. Wtedy zwróćiłbym wszystkie dane razem dla całego profilu. Czyli kto, co kupił i za ile. Piszesz o tabelkach w bazie, wieć pewnie da się to wyciągnąc jednym zapytaniem.
  2. Jeśli jednak masz osobne komponenty na froncie i zależy Ci na 3 osobnych callach do backendu, wtedy wystawiłbym 3 konretne endpointy z tym co potrzeba. User pewnie mógłby zostać taki jak pokazałeś i nie ma sensu robić osobnego endpointu. Ale i tak możesz. Ostatnie zamówienia i ostatnie kupione produkty to pewnie osobne endpointy bym zrobił które zwracają już to co trzeba.
MA
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 644
1

To też zależy od tego jak zbudowany jest zespół.

Jeżeli jeden zespół/osoba robi front i back to rozwiązanie @AreQrm jest spoko bo mogą dowolnie sobie to rozwijać.

Jak masz osobne zespoły to warto zrobić to bardziej generycznie żeby z każdą zmianą w profilu nie trzeba było zmieniać backendu (komunikacje pomiędzy zespołami można traktować jako bottleneck), wtedy można użyć GraphQL wspomnianiego przez @Shalom.

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.