Ostatnio dowiedziałem się o GraphQL, który twierdzi, że jest lepszy od RESTful. Zacząłem się jednak zastanawiać, dlaczego po prostu nie umieszczamy instrukcji SQL w żądaniu HTTP GET.
Na przykład w GraphQL napisałbym
{
Movie(id: "cixos5gtq0ogi0126tvekxo27") {
id
title
actors {
name
}
}
}
Co nie jest dużo prostsze niż jego odpowiednik SQL
SELECT id, title FROM movies WHERE id = cixos5gtq0ogi0126tvekxo27;
SELECT actors.name FROM actors, actors_movies WHERE actors.id == movies.actor_id AND movie.id == cixos5gtq0ogi0126tvekxo27;
Może możemy zakodować zapytanie i wysłać kod na serwer
GET endpoint?q=SELECT%20id%2C%20title%20FROM%20movies%20WHERE%20id%20%3D%20cixos5gtq0ogi0126tvekxo27%3B%0ASELECT%20actors.name%20FROM%20actors%2C%20actors_movies%20WHERE%20actors.id%20%3D%3D%20movies.actor_id%20AND%20movie.id%20%3D%3D%20cixos5gtq0ogi0126tvekxo27%3B HTTP/1.1
Tak, adres URL zapytania może być zbyt długi, ale możesz go umieścić w treści żądania POST, jeśli nie zależy Ci na zgodności z REST. (Nawiasem mówiąc, myślę, że RFC HTTP musi zostać zmieniony, aby REST miał sens: ograniczenie długości ciągów zapytań powoduje mieszanie implementacji ze specyfikacją na samym początku)
Zaletą jest także bezpośrednie wydawanie kodu SQL od klienta
- Do analizowania GraphQL nie jest wymagany kod / biblioteka po stronie serwera, co skraca czas programowania.
- Do przeanalizowania GraphQL nie jest potrzebny narzut po stronie serwera, co skraca czas działania.
- Instrukcje SQL są znacznie bardziej elastyczne niż GraphQL, ponieważ (w większości przypadków) te ostatnie i tak zredukują się do SQL.
- Wszyscy znają SQL.
Jakie zalety ma GraphQL w stosunku do SQL?
Odpowiedzi:
Zasadniczo abstrakcja.
SQL wymaga od klientów znajomości dokładnej struktury bazy danych, co nie jest dobre. Na dodatek analiza SQL w celu wykonania specjalnych operacji na podstawie wartości wysyłanej jako dane wejściowe jest naprawdę trudna. Istnieją całe programy, które są w zasadzie odpowiedzialne tylko za to. Czy wiesz co to są? Jeśli odgadłeś bazy danych, masz rację.
Dzięki temu, że SQL nie jest bezpośrednio ujawniany, użytkownik nie ogranicza konsumenta interfejsu API do wewnętrznej reprezentacji bazy danych. Z łatwością wystawiasz tylko to, co chcesz.
A ponieważ klienci interfejsu API zależą tylko od abstrakcji, możesz mieć jak najwięcej warstw między danymi wejściowymi API a rzeczywistą bazą danych (bezpieczeństwo, buforowanie, ładowanie danych z wielu baz danych na jedno żądanie, ...).
W przypadku usług publicznych bezpośrednie ujawnienie bazy danych prawie nigdy nie jest właściwym podejściem. Jeśli jednak masz kilka systemów wewnętrznych, jasne, twoje podejście może mieć sens, ale nawet wtedy łatwiejsze może być połączenie z bazą danych aplikacji A bezpośrednio z aplikacji B, podając poświadczenia bazy danych dla aplikacji B, zamiast próbować wymyślić z niestandardowym interfejsem HTTP dla języka SQL bazy danych.
Ponieważ to nie jest łatwe. Nawet jeśli ktoś używa bardzo prostego zapytania, takiego jak:
jak upewnić się, że wynik jest odpowiednio buforowany? To zapytanie zawiera znaki nowej linii, ale ktoś równie dobrze mógłby napisać zapytanie w następujący sposób:
i nadal powinien być buforowany w taki sam sposób jak powyższy. W szczególności podałem miejsce, w którym wyszukiwanie ciągów zawiera nową linię, więc po prostu znalezienie końcówek linii i zastąpienie ich spacją tutaj nie zadziała, prawidłowe przetworzenie żądania byłoby znacznie bardziej skomplikowane.
Nawet jeśli to naprawisz, kolejne zapytanie może zmienić kolejność warunków, a zapytanie będzie wyglądać następująco:
a kolejne żądanie może zawierać zbędny
WHERE
argument, taki jak ten:Wszystkie te zapytania powinny nadal zwracać ten sam wynik, powinny być buforowane w ten sam sposób. Ale obsługa wszystkich możliwych opcji jest prawie niemożliwa. Dlatego nie można po prostu porównać adresu URL z kluczami w Redis.
źródło
Teoretycznie nie ma powodu, dla którego nie można ujawnić takiego interfejsu SQL.
W praktyce SQL jest zdecydowanie zbyt potężny, aby skutecznie ograniczać się do zakresu bezpieczeństwa, który chcesz ujawnić.
Nawet jeśli zezwolisz tylko na dostęp do odczytu, złe zapytanie może nadal przenosić zasoby.
Inne języki, takie jak graphQL, zostały zaprojektowane do ujawnienia. Dają jedynie użytkownikom opcję filtrowania tego, co już widzieli.
Zaletą używania tych języków jest to, że przeszli przez wszystkie rzeczy, których nie chcesz, aby użytkownicy robili w SQL i zdjęli je ze stołu.
źródło
Jak wspomnieli inni, ujawnianie SQL bezpośrednio w interfejsie API jest bardzo złą opcją. GraphQL, pomimo swojej nazwy, nie jest abstrakcją dla SQL, ale dla dowolnego magazynu danych, a nawet innych usług.
Jeśli szukasz abstrakcji zbliżonej do SQL, możesz rzucić okiem na odata (jeśli akurat pracujesz w backendach .NET, choć może istnieją inne implementacje).
źródło
jeśli chcesz wystawiać SQL jak GraphQL, możesz potrzebować czegoś takiego jak GraphQL, ponieważ będziesz musiał ukryć ważne informacje i wybrać to, co chcesz pokazać w interfejsie API, to dla bezpieczeństwa.
GraphQl i SQL to różne rzeczy, SQL to język zapytań do DataBase, a GraphQL służy tylko do zarządzania danymi z API, w API będziesz musiał stworzyć własne schematy do wyświetlenia i zapytania do zarządzania nimi itp.
w każdym interfejsie API będziesz musiał zrobić te rzeczy dla bezpieczeństwa, ale jeśli chcesz czegoś, co jest darmowym dostępem do danych, może zadziałałoby, znasz tak wiele alternatyw w świecie oprogramowania
źródło