Por que não usar SQL em vez de GraphQL?

20

Recentemente, eu aprendi sobre o GraphQL, que afirma ser superior ao RESTful. No entanto, comecei a me perguntar por que simplesmente não colocamos instruções SQL em uma solicitação HTTP GET.

Por exemplo, no GraphQL eu escreveria

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

O que não é muito mais simples que seu equivalente 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;

Talvez possamos codificar a consulta por URL e enviar para o 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

Sim, o URL da consulta pode ser muito longo, mas você pode colocá-lo no corpo de uma solicitação POST se não se importar com a conformidade com REST. (A propósito, acho que o RFC HTTP precisa ser revisado para que o REST faça sentido: limitar o tamanho das cadeias de consulta mistura implementação com especificação no início)

A emissão direta de SQL do cliente também tem a vantagem de

  1. Nenhum código / biblioteca do lado do servidor é necessário para analisar o GraphQL, reduzindo o tempo de desenvolvimento.
  2. Nenhuma sobrecarga do lado do servidor é necessária para analisar o GraphQL, reduzindo o tempo de execução.
  3. As instruções SQL são muito mais flexíveis que o GraphQL porque (na maioria dos casos) as últimas serão reduzidas para SQL de qualquer maneira.
  4. Todo mundo conhece SQL.

Então, quais são as vantagens do GraphQL sobre o SQL?

nalzok
fonte
41
Mesas de Bobby pequenas.
Philip Kendall
1
1. Ainda posso fazer DoS com consultas SQL arbitrariamente complicadas. 2. Não há chance de um ator mal-intencionado obter uma chave válida ...
Philip Kendall
3
@PhilipKendall Você está certo, mas o uso do GraphQL (ou REST ou o que for) também não resolve esses problemas, certo?
nalzok 6/04
7
@nalzok: SQL é Turing-completo, o que significa que é impossível validar estaticamente.
Jörg W Mittag
3
Isso é muito simples de entender por que é uma péssima ideia. Implemente você mesmo. Em algum momento, você perceberá que está investindo o tempo principalmente em uma coisa: segurança. Não muito tarde, você se sentirá um pouco chateado porque está implementando um TOAD com capa. Então você perceberá o quão difícil é o mapeamento de linhas em todo o sistema e tentará reinventar a roda ORM dos dois lados: cliente e servidor. No momento em que você desiste, seu PM solicita um relatório: como está o serviço dos usuários ? Está feito? "...
Laiv 06/04

Respostas:

30

Basicamente, abstração.

O SQL exige que seus clientes conheçam sua estrutura exata do banco de dados, o que não é bom. Além disso, analisar o SQL para executar operações especiais com base no valor enviado como entrada é uma coisa realmente difícil de fazer. Existem softwares inteiros que são praticamente responsáveis ​​apenas por isso. Você sabe o que são? Se você adivinhou os bancos de dados, está certo.

Graças a não expor o SQL diretamente, você não está limitando o consumidor da API à representação interna do seu banco de dados. Você expõe facilmente apenas o que deseja expor.

E como os clientes da API dependem apenas da abstração, você é livre para ter o maior número possível de camadas entre a entrada da API e o banco de dados real (segurança, armazenamento em cache, carregamento de dados de vários bancos de dados em uma única solicitação, ...).

Para serviços públicos, expor um banco de dados diretamente nunca é a abordagem correta. No entanto, se você tiver alguns sistemas internos, sua abordagem poderá fazer sentido, mas mesmo assim poderá ser mais fácil conectar-se ao banco de dados do aplicativo A diretamente do Aplicativo B, fornecendo as credenciais do banco de dados ao Aplicativo B, em vez de tentar avançar. com uma interface HTTP customizada para a linguagem SQL do banco de dados.


Por que não consigo comparar a URL (ou consulta SQL) com as chaves no Redis antes de executar a consulta real no RDBMS?

Porque não é fácil. Mesmo se alguém usar uma consulta muito simples, 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'

como você garante que o resultado seja armazenado em cache corretamente? Essa consulta inclui novas linhas, mas alguém também poderia escrever a consulta da seguinte maneira:

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 ainda deve ser armazenado em cache da mesma maneira que o acima. Incluí especificamente um local em que uma pesquisa de string contém uma nova linha; portanto, simplesmente encontrar terminações de linha e substituí-las por um espaço não funcionará aqui; analisar a solicitação corretamente seria muito mais complicado.

E mesmo se você corrigir isso, outra consulta poderá mudar a ordem das condições e a consulta terá a seguinte aparência:

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 outra solicitação pode conter um 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'

Todas essas consultas ainda devem retornar o mesmo resultado, devem ser armazenadas em cache da mesma maneira. Mas lidar com todas as opções possíveis é praticamente impossível. É por isso que você não pode simplesmente comparar o URL com as chaves no Redis.

Andy
fonte
Esta é uma boa resposta, mas consulte a atualização.
nalzok 7/04
19

Em teoria, não há razão para que você não possa expor uma interface SQL como esta.

Na prática, o SQL é poderoso demais para ser efetivamente limitado ao escopo de segurança que você deseja expor.

Mesmo se você permitir apenas o acesso de leitura, uma consulta incorreta ainda poderá consumir recursos.

Outras linguagens como o graphQL foram projetadas para serem expostas. Eles estão apenas dando aos usuários uma opção de filtro sobre o que eles já podem ver.

A vantagem de usar essas linguagens é que elas passaram por todas as coisas que você gostaria de interromper os usuários no SQL e as retiraram da mesa.

Ewan
fonte
2
Obrigado pela resposta, mas você poderia explicar como o GraphQL resolve o problema da drenagem de recursos? Uma consulta desonesta do GraphQL ainda pode dizer "conte-me tudo sobre cada filme e seus atores", resultando em um gráfico enorme e esgotando meu DBMS e minha rede.
nalzok 7/04
Mas eu posso escrever uma consulta SQL recursiva que irá bloquear sua tabela e impedir que outros usuários executem qualquer consulta
Ewan
4
o problema não é tanto restringir o acesso às tabelas ou excluir, mas a complexidade de cisalhamento do SQL. você permitirá a criação da tabela temporária? que tal executar CLI? rotações? transações? sub seleciona? cursores? como você vai distinguir quando o uso dessas coisas é aceitável e quando é "ruim"?
Ewan
2

Como outros já mencionaram, expor o SQL diretamente na API é uma opção muito ruim. Apesar do nome, o GraphQL não é uma abstração para o SQL, mas para qualquer armazenamento de dados ou mesmo outros serviços.

Se você está procurando uma abstração mais próxima do SQL, pode dar uma olhada no odata (se trabalhar em back- end do .NET, embora outras implementações existam).

jannikb
fonte
0

se você quiser expor SQL como o GraphQL, poderá precisar de algo como o GraphQL, porque precisará ocultar as informações importantes e selecionar o que deseja mostrar na API, por segurança.

GraphQl e SQL são coisas diferentes, SQL é a linguagem para consultar o DataBase e GraphQL é apenas para gerenciar os dados da API, na API, você precisará fazer seus esquemas para mostrar e consultas para gerenciá-lo, etc.

em qualquer API, você precisará fazer essas coisas simplesmente por segurança, mas se você quiser algo que seja acesso gratuito a dados, talvez funcione, você conhece muitas alternativas no mundo do software

Buraco negro
fonte