GraphQL 대신 SQL을 사용하지 않는 이유는 무엇입니까?


20

최근에는 RESTful보다 우수하다고 주장하는 GraphQL에 대해 배웠습니다. 그러나 왜 단순히 SQL 문을 HTTP GET 요청에 넣지 않는지 궁금해지기 시작했습니다.

예를 들어 GraphQL에서는

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

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;

쿼리를 URL 인코딩하고 서버로 보낼 수 있습니다.

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

예, 쿼리 URL이 너무 길 수 있지만 REST 준수에 신경 쓰지 않으면 POST 요청 본문에 넣을 수 있습니다. (그런데 REST가 이해하기 위해 HTTP RFC를 수정해야한다고 생각합니다. 쿼리 문자열의 길이를 제한하면 구현이 사양과 처음부터 혼합됩니다)

클라이언트에서 직접 SQL을 발행하면 다음과 같은 이점이 있습니다.

  1. GraphQL을 구문 분석하는 데 서버 측 코드 / 라이브러리는 필요하지 않으므로 개발 시간이 단축됩니다.
  2. GraphQL을 구문 분석하는 데 서버 측 오버 헤드가 필요하지 않으므로 런타임이 줄어 듭니다.
  3. SQL 문은 GraphQL보다 훨씬 융통성이 있습니다. 왜냐하면 대부분의 경우 후자는 SQL로 줄어 듭니다.
  4. 누구나 SQL을 알고 있습니다.

그렇다면 GraphQL이 SQL에 비해 어떤 이점이 있습니까?


41
작은 바비 테이블.
Philip Kendall

1
1. 여전히 복잡한 SQL 쿼리로 DoS를 수행 할 수 있습니다. 2. 악의적 인 행위자가 유효한 키를 얻을 가능성은 없습니다 ...
Philip Kendall

3
@PhilipKendall 맞습니다. 그러나 GraphQL (또는 REST 등)을 사용해도 이러한 문제가 해결되지 않습니까?
nalzok

7
@nalzok : SQL이 Turing-complete이므로 정적으로 유효성을 검사 할 수 없습니다.
Jörg W Mittag

3
이것이 왜 끔찍한 아이디어인지 이해하는 것은 매우 간단합니다. 직접 구현하십시오. 어느 시점에서, 당신은 당신이 시간을 대부분 한 가지에 투자하고 있음을 알게 될 것입니다 : 보안. 너무 늦지 않은 당신은 뚜껑이 달린 TOAD를 구현하고 있기 때문에 다소 화를 느낄 것입니다. 그런 다음 시스템 전체에서 행을 맵핑하는 것이 얼마나 어려운지 알 수 있으며 클라이언트와 서버의 양쪽에서 ORM 휠을 재발 명하려고 시도합니다. 포기할 때마다 PM은 보고서를 요청합니다 . 사용자 서비스는 어떻게 진행되고 있습니까? 끝났어? "...
Laiv

답변:


30

기본적으로 추상화.

SQL은 클라이언트가 정확한 데이터베이스 구조를 알고 있어야하는데 이는 좋지 않습니다. 또한 입력으로 전송 된 값을 기반으로 특수 작업을 수행하기 위해 SQL을 분석하는 것은 실제로 어려운 작업입니다. 그에 대해서만 책임이있는 전체 소프트웨어가 있습니다. 그게 뭔지 알아? 데이터베이스를 추측했다면 맞습니다.

SQL을 직접 노출시키지 않기 때문에 API 소비자를 데이터베이스의 내부 표현으로 제한하지 않습니다. 노출하려는 대상 만 쉽게 노출합니다.

그리고 API의 클라이언트는 추상화에만 의존하기 때문에 API 입력과 실제 데이터베이스 (보안, 캐싱, 단일 요청으로 여러 데이터베이스에서 데이터로드 등) 사이에 가능한 많은 계층을 자유롭게 가질 수 있습니다.

공공 서비스의 경우 데이터베이스를 직접 노출하는 것은 결코 올바른 접근법이 아닙니다. 그러나 내부 시스템이 몇 개인 경우 접근 방식이 의미가있을 수 있지만 데이터베이스 자격 증명을 응용 프로그램 B에 제공하지 않고 응용 프로그램 B에서 직접 응용 프로그램 A의 데이터베이스에 연결하는 것이 더 쉬울 수 있습니다. 데이터베이스 SQL 언어에 대한 사용자 정의 HTTP 인터페이스


RDBMS에서 실제 쿼리를 수행하기 전에 URL (또는 SQL 쿼리)을 Redis의 키와 비교할 수없는 이유는 무엇입니까?

쉽지 않기 때문에. 누군가가 다음과 같은 매우 간단한 쿼리를 사용하더라도

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'

결과가 올바르게 캐시되는지 어떻게 확인합니까? 이 쿼리에는 줄 바꿈이 포함되지만 누군가 다음과 같은 방법으로 쿼리를 작성할 수도 있습니다.

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'

그리고 여전히 위와 같은 방식으로 캐시되어야합니다. 문자열 검색에 새 줄이 포함되는 위치를 구체적으로 포함 했으므로 단순히 줄 끝을 찾아 공백으로 바꾸는 것은 작동하지 않으므로 요청을 올바르게 구문 분석하는 것이 훨씬 더 복잡합니다.

그리고 그것을 고치더라도 다른 쿼리는 조건의 순서를 바꿀 수 있으며 쿼리는 다음과 같습니다.

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'

다른 요청에는 다음 WHERE과 같은 중복 인수 가 포함될 수 있습니다 .

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'

이러한 모든 쿼리는 여전히 동일한 결과를 반환해야하며 동일한 방식으로 캐시되어야합니다. 그러나 가능한 모든 옵션을 처리하는 것은 거의 불가능합니다. 그렇기 때문에 URL을 Redis의 키와 단순히 비교할 수 없습니다.


이것은 좋은 대답이지만 업데이트를 참조하십시오.
nalzok

19

이론적으로 이와 같은 SQL 인터페이스를 공개 할 수없는 이유는 없습니다.

실제로 SQL은 노출하려는 보안 범위로 효과적으로 제한하기에는 너무 강력합니다.

읽기 액세스 만 허용하더라도 잘못된 쿼리는 여전히 리소스를 사용할 수 있습니다.

graphQL과 같은 다른 언어는 노출되도록 설계되었습니다. 그들은 단지 사용자에게 이미 볼 수있는 것에 대한 필터 옵션을 제공합니다.

이러한 언어를 사용하면 SQL에서 사용자가 수행하지 못하게하고 테이블에서 제외하려는 모든 작업을 수행 할 수 있다는 이점이 있습니다.


2
답변 주셔서 감사하지만 GraphQL이 리소스 소모 문제를 해결하는 방법을 설명 할 수 있습니까? 불량 GraphQL 쿼리는 여전히“각 영화와 배우에 대한 모든 것을 말해줘”라고 말하여 막대한 그래프를 생성하고 DBMS와 네트워크를 소진합니다.
nalzok

그러나 나는 테이블을 잠그고 다른 사용자가 쿼리를 전혀 실행하지 못하게하는 재귀 SQL 쿼리를 작성할 수 있습니다.
Ewan

4
문제는 테이블에 대한 액세스를 제한하거나 삭제하는 것이 아니라 SQL의 전단 복잡성입니다. 임시 테이블 생성을 허용합니까? CLI 실행은 어떻습니까? 루프? 업무? 하위 선택? 커서? 이러한 것들의 사용이 허용되는시기와 '나쁜'시기를 어떻게 구분할 것인가
Ewan

2

다른 사람들이 언급했듯이 API에 SQL을 직접 노출시키는 것은 매우 나쁜 옵션입니다. GraphQL은 이름에도 불구하고 SQL에 대한 추상화가 아니라 데이터 저장소 또는 다른 서비스에 대한 추상화입니다.

SQL에 더 가까운 추상화를 찾고 있다면 odata살펴볼 수 있습니다 (.NET 백엔드에서 작업하는 경우 다른 구현이있을 수 있음).


0

GraphQL과 같은 SQL을 노출하려면 중요한 정보를 숨기고 API에 표시 할 항목 (보안을 위해)을 선택해야하므로 GraphQL과 같은 것이 필요할 수 있습니다.

GraphQl과 SQL은 서로 다릅니다. SQL은 DataBase를 쿼리하는 언어이고 GraphQL은 API의 데이터를 관리하기위한 것입니다. API에서는 스키마를 표시하고 관리하기위한 쿼리 등을 만들어야합니다.

모든 API에서 단순히 보안을 위해 그러한 것들을 만들어야하지만 무료 데이터 액세스가 가능한 무언가를 원한다면 소프트웨어 세계에서 많은 대안을 알고 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.