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.
GET /user/{id}
{
"id": "user123",
"email" : "[email protected]",
"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ź zGET/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.
GET /product/simplified/{id}
{
"name": "carpenter's hammer",
"photoUrl" : "http.."
}
- GraphQL