Perché non usare SQL invece di GraphQL?


20

Recentemente ho appreso di GraphQL che afferma di essere superiore a RESTful. Tuttavia, ho iniziato a chiedermi perché non inseriamo semplicemente le istruzioni SQL in una richiesta HTTP GET.

Ad esempio, in GraphQL vorrei scrivere

{
  Movie(id: "cixos5gtq0ogi0126tvekxo27") {
    id
    title
    actors {
      name
    }
  }
}

Che non è molto più semplice della sua controparte 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;

Forse possiamo codificare l'URL della query e inviarla al server

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

Sì, l'URL della query può essere troppo lungo, ma puoi inserirlo nel corpo di una richiesta POST se non ti interessa la conformità REST. (A proposito, penso che l'RFC HTTP debba essere rivisto perché REST abbia un senso: limitare la lunghezza delle stringhe di query mescola l'implementazione con le specifiche all'inizio)

Anche l'emissione diretta di SQL dal client ha il vantaggio di

  1. Non è necessario alcun codice / libreria sul lato server per analizzare GraphQL, riducendo i tempi di sviluppo.
  2. Non è necessario alcun sovraccarico sul lato server per analizzare GraphQL, riducendo il tempo di esecuzione.
  3. Le istruzioni SQL sono molto più flessibili di GraphQL perché (nella maggior parte dei casi) queste ultime si ridurranno comunque a SQL.
  4. Tutti conoscono SQL.

Quindi, quali sono i vantaggi di GraphQL rispetto a SQL?


41
Tavolini Bobby.
Philip Kendall,

1
1. Posso ancora farti domande SQL arbitrariamente complicate. 2. Non c'è alcuna possibilità che un attore malintenzionato possa ottenere una chiave valida ...
Philip Kendall,

3
@PhilipKendall Hai ragione, ma l'utilizzo di GraphQL (o REST o altro) non risolve questi problemi, giusto?
nalzok,

7
@nalzok: SQL è Turing-complete, il che significa che è impossibile convalidare staticamente.
Jörg W Mittag,

3
Questo è molto semplice da capire perché è un'idea terribile. Implementalo tu stesso. Ad un certo punto, ti renderai conto che stai investendo il tempo principalmente in 1 cosa: la sicurezza. Non troppo tardi ti sentirai un po 'arrabbiato perché stai implementando un TOAD limitato. Quindi ti renderai conto di quanto sia difficile mappare le righe su tutto il sistema e proverai a reinventare la ruota ORM su entrambi i lati: client e server. Quando ti arrendi, il tuo PM ti chiederà un rapporto: come va il servizio degli utenti ? È fatta? "...
Laiv

Risposte:


30

Fondamentalmente, astrazione.

SQL richiede ai tuoi clienti di conoscere la struttura esatta del tuo database, il che non va bene. Inoltre, analizzare l'SQL per eseguire operazioni speciali basate sul valore inviato come input è una cosa davvero difficile da fare. Ci sono interi software che sono praticamente responsabili solo per quello. Sai cosa sono quelli? Se hai indovinato i database, hai ragione.

Grazie a non esporre direttamente l'SQL, non stai limitando il consumatore dell'API alla rappresentazione interna del tuo database. Esponi facilmente solo ciò che vuoi esporre.

E poiché i client dell'API dipendono solo dall'astrazione, sei libero di avere il maggior numero possibile di livelli tra l'input dell'API e il database effettivo (sicurezza, memorizzazione nella cache, caricamento dei dati da più database su una singola richiesta, ...).

Per i servizi pubblici, esporre direttamente un database non è praticamente l'approccio giusto. Se tuttavia disponi di alcuni sistemi interni, il tuo approccio potrebbe avere senso, ma anche in questo caso potrebbe essere più semplice connettersi al database dell'applicazione A direttamente dall'applicazione B, fornendo le credenziali del database all'applicazione B, piuttosto che cercare di trovare con un'interfaccia HTTP personalizzata per il linguaggio SQL del database.


Perché non posso semplicemente confrontare l'URL (o la query SQL) con le chiavi in ​​Redis prima di eseguire la query effettiva su RDBMS?

Perché non è facile. Anche se qualcuno utilizza una query molto semplice, come ad esempio:

SELECT st.id, jt.name
FROM some_table st
INNER JOIN join_table jt ON jt.some_table_id = st.id
WHERE st.name = 'hello
world' AND st.type = 'STANDARD'

come assicurarsi che il risultato sia correttamente memorizzato nella cache? Questa query include newline, ma qualcuno potrebbe anche scrivere la query nel modo seguente:

SELECT st.id, jt.name FROM some_table st INNER JOIN join_table jt ON jt.some_table_id = st.id WHERE st.name = 'hello
world' AND st.type = 'STANDARD'

e dovrebbe ancora essere memorizzato nella cache allo stesso modo di quello sopra. Ho incluso specificamente un punto in cui una ricerca di stringhe contiene una nuova linea, quindi semplicemente trovare i finali di linea e sostituirli con uno spazio non funzionerà qui, analizzare correttamente la richiesta sarebbe molto più complicato.

E anche se lo risolvi, un'altra query potrebbe cambiare l'ordine delle condizioni e la query sarebbe simile a questa:

SELECT st.id, jt.name
FROM some_table st
INNER JOIN join_table jt ON jt.some_table_id = st.id
WHERE st.type = 'STANDARD' AND st.name = 'hello
world'

e un'altra richiesta potrebbe contenere un WHEREargomento ridondante , come questo:

SELECT st.id, jt.name
FROM some_table st
INNER JOIN join_table jt ON jt.some_table_id = st.id
WHERE st.type = 'STANDARD' AND st.name = 'hello
world' AND st.stype = 'STANDARD'

Tutte queste query dovrebbero comunque restituire lo stesso risultato, devono essere memorizzate nella cache allo stesso modo. Ma gestire tutte le possibili opzioni è praticamente impossibile. Ecco perché non puoi semplicemente confrontare l'URL con le chiavi in ​​Redis.


Questa è una bella risposta, ma si prega di consultare l'aggiornamento.
nalzok,

19

In teoria non c'è motivo per cui non è possibile esporre un'interfaccia SQL come questa.

In pratica, SQL è troppo potente per essere efficacemente limitato all'ambito di sicurezza che si desidera esporre.

Anche se si consente solo l'accesso in lettura, una query errata può comunque limitare le risorse.

Altri linguaggi come graphQL sono progettati per essere esposti. Stanno semplicemente offrendo agli utenti un'opzione di filtro su ciò che potrebbero già vedere.

Il vantaggio dell'utilizzo di questi linguaggi è che sono passati attraverso tutte le cose che vorresti impedire agli utenti di fare in SQL e li hanno tolti dal tavolo.


2
Grazie per la risposta, ma potresti spiegare come GraphQL risolve il problema dell'esaurimento delle risorse? Una query GraphQL canaglia può ancora dire "dimmi tutto di ogni film e dei loro attori", risultando in un enorme grafico e esaurendo il mio DBMS e la mia rete.
nalzok,

Ma posso scrivere una query SQL ricorsiva che bloccherà la tua tabella e impedirà ad altri utenti di eseguire qualsiasi query
Ewan

4
il problema non è tanto limitare l'accesso alle tabelle o eliminare, ma la complessità di taglio di SQL. consentirai la creazione di tabelle temporanee? che dire dell'esecuzione dell'interfaccia della riga di comando? loop? le transazioni? sub seleziona? cursori? come distinguerai quando l'uso di queste cose è accettabile e quando è "cattivo"
Ewan

2

Come altri hanno già detto, esporre SQL direttamente nell'API è una pessima opzione. GraphQL, nonostante il suo nome, non è un'astrazione per SQL, ma per qualsiasi archivio di dati o anche altri servizi.

Se stai cercando un'astrazione più vicina a SQL, potresti dare un'occhiata a odata (se ti capita di lavorare con back- end .NET, anche se forse esistono altre implementazioni).


0

se vuoi esporre SQL come GraphQL, potresti aver bisogno di qualcosa come GraphQL, perché dovrai nascondere le informazioni importanti e selezionare ciò che vuoi mostrare nell'API, questo per sicurezza.

GraphQl e SQL sono cose diverse, SQL è il linguaggio per interrogare DataBase e GraphQL è solo per gestire i dati dall'API, nell'API dovrai mostrare i tuoi schemi e interrogarli per gestirli, ecc.

in qualsiasi API dovrai creare queste cose semplicemente per sicurezza, ma se vuoi qualcosa che sia un accesso gratuito ai dati potrebbe funzionare, conosci così tante alternative nel mondo del software

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.