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
リトルボビーテーブル。
フィリップケンドール

1
1. arbitrarily意的に複雑なSQLクエリでDoSを実行できます。2.悪意のある攻撃者が有効なキーを取得する可能性はありません...
Philip Kendall

3
@PhilipKendallあなたは正しいですが、GraphQL(またはRESTなど)を使用してもこれらの問題は解決しませんか?
nalzok

7
@nalzok:SQLはチューリング完全です。つまり、静的に検証することは不可能です。
イェルクWミッターク

3
これはなぜそれがひどいアイデアなのかを理解するのは非常に簡単です。自分で実装してください。ある時点で、あなたは主に1つのことに時間を費やしていることに気付くでしょう:セキュリティ。遅すぎずに、キャップ付きのTOADを実装しているので、多少混乱するでしょう。次に、システム全体で行をマッピングすることがどれほど難しいかを理解し、クライアントとサーバーの両方でORMホイールを再発明しようとします。あきらめるまでに、PMからレポートを求められます。ユーザーのサービスはどのように進んでいますか?終わった?"...
Laiv

回答:


30

基本的に、抽象化。

SQLでは、クライアントが正確なデータベース構造を知る必要がありますが、これは良くありません。さらに、入力として送信された値に基づいて特別な操作を実行するためにSQLを分析することは、本当に難しいことです。それだけを担当するソフトウェア全体があります。それらが何であるか知っていますか?データベースを推測した場合、あなたは正しいです。

SQLを直接公開しないため、APIのコンシューマーをデータベースの内部表現に制限していません。簡単に公開したいものだけを公開します。

また、APIのクライアントは抽象化のみに依存しているため、API入力と実際のデータベース(セキュリティ、キャッシュ、1回のリクエストで複数のデータベースからデータを読み込むなど)の間に可能な限り多くのレイヤーを自由に配置できます。

公共サービスの場合、データベースを直接公開することはほとんど適切なアプローチではありません。ただし、内部システムがいくつかある場合は、あなたのアプローチは理にかなっているかもしれませんが、それでも、アプリケーションBにデータベース資格情報を与えることで、アプリケーションBから直接アプリケーションAのデータベースに接続する方が簡単な場合がありますデータベースSQL言語用のカスタムHTTPインターフェイス。


RDBMSで実際のクエリを実行する前に、RedisのキーとURL(またはSQLクエリ)を単に比較できないのはなぜですか?

簡単ではないからです。誰かが次のような非常に単純なクエリを使用している場合でも:

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'

これらのクエリはすべて同じ結果を返すことになっていますが、同じ方法でキャッシュする必要があります。しかし、すべての可能なオプションを処理することはほとんど不可能です。そのため、RedisのキーとURLを単純に比較することはできません。


これはいい答えですが、アップデートをご覧ください。
nalzok

19

理論的には、このようなSQLインターフェイスを公開できない理由はありません。

実際には、SQLは非常に強力すぎて、公開したいセキュリティスコープに効果的に制限できません。

読み取りアクセスのみを許可しても、不適切なクエリはリソースを独占する可能性があります。

graphQLなどの他の言語は、公開されるように設計されています。それらは単に、ユーザーが既に見ることができるものにフィルターオプションを提供しているだけです。

これらの言語を使用する利点は、ユーザーがSQLで実行するのを止めたいと思うすべてのことを実行し、それらをテーブルから削除したことです。


2
答えてくれてありがとう、しかしGraphQLがリソースの流出の問題をどのように解決するか説明していただけますか 不正なGraphQLクエリは、「各映画とその俳優に関するすべてを教えてください」と言うことができ、その結果、巨大なグラフが作成され、DBMSとネットワークが使い果たされます。
nalzok

しかし、テーブルをロックし、他のユーザーがクエリを実行できないようにする再帰的SQLクエリを書くことができます
Ewan

4
問題は、テーブルへのアクセスの制限や削除ではなく、SQLの複雑さです。一時テーブルの作成を許可しますか?CLIの実行はどうですか?ループ?トランザクション?サブセレクト?カーソル?これらのものの使用が許容される場合と、その「悪い」場合とをどのように区別しますか
ユアン

2

他の人が述べたように、APIでSQLを直接公開することは非常に悪いオプションです。GraphQLは、その名前にもかかわらず、SQLの抽象化ではなく、データストアや他のサービスの抽象化です。

SQLに近い抽象化を探している場合は、odataを調べてみてください(他の実装が存在する場合でも、.NETバックエンドで作業している場合)。


0

GraphQLのようなSQLを公開したい場合、重要な情報を非表示にし、APIで表示するものを選択する必要があるため、GraphQLなどが必要になります。これはセキュリティのためです。

GraphQlとSQLは別のものです。SQLはデータベースを照会するための言語であり、GraphQLはAPIからデータを管理するためだけのものです。

どのAPIでも、単純にセキュリティを確保するためにこれらを作成する必要がありますが、無料のデータアクセスで動作するものが必要な場合は、ソフトウェアの世界で非常に多くの選択肢があります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.