¿Por qué no usar SQL en lugar de GraphQL?

20

Recientemente aprendí sobre GraphQL que dice ser superior a RESTful. Sin embargo, comencé a preguntarme por qué no simplemente ponemos declaraciones SQL en una solicitud HTTP GET.

Por ejemplo, en GraphQL escribiría

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

Lo cual no es mucho más simple que su contraparte 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;

Tal vez podamos codificar con URL la consulta y enviarla al servidor

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í, la URL de consulta puede ser demasiado larga, pero puede incluirla en el cuerpo de una solicitud POST si no le importa el cumplimiento de REST. (Por cierto, creo que el RFC de HTTP necesita ser revisado para que REST tenga sentido: limitar la longitud de las cadenas de consulta combina la implementación con la especificación desde el principio)

La emisión directa de SQL desde el cliente también tiene la ventaja de

  1. No se requiere código / biblioteca del lado del servidor para analizar GraphQL, lo que reduce el tiempo de desarrollo.
  2. No se necesita una sobrecarga del lado del servidor para analizar GraphQL, lo que reduce el tiempo de ejecución.
  3. Las declaraciones SQL son mucho más flexibles que GraphQL porque (en la mayoría de los casos) este último se reducirá a SQL de todos modos.
  4. Todos conocen SQL.

Entonces, ¿qué ventajas tiene GraphQL sobre SQL?

nalzok
fuente
41
Mesitas Bobby.
Philip Kendall
1
1. Todavía puedo hacer DoS con consultas SQL arbitrariamente complicadas. 2. No hay posibilidad de que un actor malicioso obtenga una clave válida ...
Philip Kendall
3
@PhilipKendall Tienes razón, pero usar GraphQL (o REST o lo que sea) tampoco resuelve estos problemas, ¿verdad?
nalzok
77
@nalzok: SQL es Turing completo, lo que significa que es imposible validar estáticamente.
Jörg W Mittag
3
Esto es muy simple de entender por qué es una idea terrible. Impleméntalo tú mismo. En algún momento, te darás cuenta de que estás invirtiendo el tiempo principalmente en 1 cosa: seguridad. No demasiado tarde, se sentirá algo molesto porque está implementando un TOAD con capa. Entonces te darás cuenta de lo difícil que es mapear filas en todo el sistema e intentarás reinventar la rueda ORM en ambos lados: cliente y servidor. Cuando te rindas, tu PM te pedirá un informe: ¿cómo va el servicio de los usuarios ? ¿Está hecho? "...
Laiv

Respuestas:

30

Básicamente, abstracción.

SQL requiere que sus clientes conozcan la estructura exacta de su base de datos, lo cual no es bueno. Además de eso, analizar el SQL para realizar operaciones especiales basadas en el valor enviado como entrada es algo realmente difícil de hacer. Hay softwares completos que son más que responsables de eso. ¿Sabes cuáles son esos? Si ha adivinado las bases de datos, tiene razón.

Gracias a no exponer el SQL directamente, no está limitando al consumidor de la API a la representación interna de su base de datos. Expone fácilmente solo lo que quiere exponer.

Y dado que los clientes de la API dependen solo de la abstracción, usted es libre de tener tantas capas como sea posible entre la entrada de la API y la base de datos real (seguridad, almacenamiento en caché, carga de datos de múltiples bases de datos en una sola solicitud, ...).

Para los servicios públicos, exponer una base de datos directamente casi nunca es el enfoque correcto. Sin embargo, si tiene algunos sistemas internos, su enfoque podría tener sentido, pero incluso así podría ser más fácil conectarse a la base de datos de la aplicación A directamente desde la Aplicación B al proporcionar las credenciales de la base de datos a la Aplicación B, en lugar de intentar aparecer con una interfaz HTTP personalizada para el lenguaje SQL de la base de datos.


¿Por qué no puedo simplemente comparar la URL (o consulta SQL) con las claves en Redis antes de realizar la consulta real en el RDBMS?

Porque no es fácil. Incluso si alguien usa una consulta muy simple, como:

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'

¿Cómo se asegura de que el resultado se almacena en caché correctamente? Esta consulta incluye nuevas líneas, pero alguien podría escribir la consulta de la siguiente manera:

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'

y todavía se supone que se debe almacenar en caché de la misma manera que la anterior. He incluido específicamente un lugar en el que una búsqueda de cadena contiene una nueva línea, por lo que simplemente encontrar terminaciones de línea y reemplazarlas con un espacio no funcionará aquí, analizar la solicitud correctamente sería mucho más complicado.

E incluso si soluciona eso, otra consulta podría cambiar el orden de las condiciones y la consulta se vería así:

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'

y otra solicitud podría contener un WHEREargumento redundante , como este:

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'

Se supone que todas esas consultas deben devolver el mismo resultado, deben almacenarse en caché de la misma manera. Pero manejar todas las opciones posibles es prácticamente imposible. Es por eso que no puede simplemente comparar la URL con las claves en Redis.

Andy
fuente
Esta es una buena respuesta, pero por favor vea la actualización.
nalzok
19

En teoría, no hay ninguna razón por la que no pueda exponer una interfaz SQL como esta.

En la práctica, SQL es demasiado poderoso para limitarse efectivamente al alcance de seguridad que desea exponer.

Incluso si solo permite el acceso de lectura, una consulta incorrecta aún puede acaparar recursos.

Otros lenguajes como graphQL están diseñados para exponerse. Simplemente están dando a los usuarios una opción de filtro sobre lo que ya pueden ver.

El beneficio de usar estos lenguajes es que han pasado por todas las cosas que querrías evitar que los usuarios hagan en SQL y los hayan sacado de la mesa.

Ewan
fuente
2
Gracias por la respuesta, pero ¿podría explicar cómo GraphQL resuelve el problema del drenaje de recursos? Una consulta de GraphQL no autorizada todavía puede decir "cuéntame todo acerca de cada película y sus actores", lo que resulta en un gráfico enorme y agota mi DBMS y mi red.
nalzok
Pero puedo escribir una consulta SQL recursiva que bloqueará su tabla y evitará que otros usuarios realicen consultas
Ewan
44
El problema no es tanto restringir el acceso a las tablas o eliminar, sino la complejidad de corte de SQL. ¿permitirá la creación de la tabla temporal? ¿Qué hay de ejecutar CLI? bucles? ¿actas? sub selecciona? cursores? ¿cómo va a distinguir cuando el uso de estas cosas es aceptable y cuando su 'mala'
Ewan
2

Como otros han mencionado, exponer SQL directamente en la API es una muy mala opción. GraphQL, a pesar de su nombre, no es una abstracción para SQL, sino para cualquier almacén de datos o incluso otros servicios.

Si está buscando una abstracción más cercana a SQL, es posible que desee echar un vistazo a los datos (si trabaja en backends .NET, aunque quizás existan otras implementaciones).

jannikb
fuente
0

si desea exponer SQL como GraphQL, podría necesitar algo como GraphQL, porque necesitará ocultar la información importante y seleccionar lo que desea mostrar en la API, esto por seguridad.

GraphQl y SQL son cosas diferentes, SQL es el lenguaje para consultar DataBase y GraphQL es solo para administrar los datos de API, en API necesitará hacer sus propios esquemas para mostrar y consultas para administrarlo, etc.

en cualquier API, necesitará hacer esas cosas simplemente por seguridad, pero si desea algo que sea acceso gratuito a datos, tal vez funcionaría, conoce muchas alternativas en el mundo del software

Calabozo
fuente