2021年6月24日木曜日

GraphQLとかより、JavaScript側からSQLを投げて、表形式でJSONを返すサーバーAPI作った方がよくないですか?

https://jp.quora.com/GraphQL%E3%81%A8%E3%81%8B%E3%82%88%E3%82%8A-JavaScript%E5%81%B4%E3%81%8B%E3%82%89SQL%E3%82%92%E6%8A%95%E3%81%92%E3%81%A6-%E8%A1%A8%E5%BD%A2%E5%BC%8F%E3%81%A7JSON%E3%82%92%E8%BF%94%E3%81%99%E3%82%B5%E3%83%BC%E3%83%90
シェアしました。


悪手と思います。簡単に理由は以下です

  • セキュリティが致命的
  • 利便性が悪い
  • 非効率

欲しいのはデータなんだからSQLなげて取得できるAPIがあれば汎用的だし効率的じゃないかと思います。と思うのは理解できます。けれども、良くはないんですよね。

何でもできるのはトレードオフとして何でもやられてしまうことを許容することになります。これによって起こされるトラブルは実に面倒臭い状況を生んでしまいます。なんだかんだ言っても製造者責任は実態として存在するので、地獄を見ることになってしまいます。

SQLを直接実行できるAPIを作ると…

一般的なシステムよりも遥かに容易に侵入が可能になります。SQLインジェクションのようなテクニックすら必要ありません。

メタデータが引けてしまえばアホ程膨大なデータ量を返すSQLを一撃で発行することが可能です。システムに大きな負荷をかけるためにDoS攻撃をかけるリスクをおかす必要がなくなります。

性能やデータ取り回しの都合上に課題がある機能で、対応のための一時表を作成・利用・破棄するSQLを発行することも可能です。データベースの構成変更が自由に行われます。コーディングをミスしてデータベースが壊れてしまうこともあるでしょう。

欲しいデータを取る目的が達成できることに対してはなかなかどうして実際に起きたら地獄を見そうな事象が並んでいると思います。他にも様々な懸念が…

上記のような懸念に地獄を見ないように対策をするとなると、きっと途中でGraphQLのようなものになったり、それを使いたくなると思います。

しかし、思い付いたアイデアを試してみるのは良いかなと思います。ブレイクスルーすることができたなら素晴らしい事で、私たちに新たな選択肢が示されることになると思います。健闘を祈ります。


さて、その方式にどのようなメリットがあるでしょうか?

まず、渡されたSQLをそのままバックエンドのデータベースに渡してはいけません。クライアントがアクセスしていいデータかどうかをチェックする必要がありますし、文法的に正当でも問題のあるクエリ構造である可能性もあります。読み込みはできるが書き込みだけ禁止したいこともあるでしょう。テーブルによっては、特定のフィールドだけ書き込み(更新)できないようなものもあるかもしれません。また、SQLは場合によってはチューリング完全である可能性もありますが、その場合は停止性が保証できないという問題もあります。

こうしたことを考えると、けっきょくサーバはJSから投げられたSQLを解析、検証する必要があります。そして、実際のバックエンドにわたす安全なSQLを改めて生成して送ることになるでしょう。

またGraphQLのようなものの場合、サーバ側では複数のバックエンドデータベースにクエリを投げてレスポンスを生成するようなことが多いと思います。そういう構成のサーバがSQLを直接受け取る場合、SQLの解析によって、どのバックエンドにクエリを発行するかといったディスパッチも考えなければなりません。

というわけで、サーバ側としては、SQLの解析等がたいへんなだけで、それほど「うまみ」がないように思います。

フロントエンド側としても、JavaScriptでSQLを生成するためのいいライブラリはないと思うので、GraphQLのようなSDKのある環境のほうが、クライアントサイドでも利便性が高いことは考えられます。


そういうわけで、「ふつうのAPIサーバ」の実装としてはそれほど良いとは思いませんが、そのほうがいい事例も考えられないわけではないですね。たとえば、「社内用データ集約基盤」のようなものの場合は、そういうものがいいかもしれません。データサイエンティストや様々なユーザが気軽に好きな構造のクエリを書いてみてデータを眺める、といった用途です。ユーザが自由にSQLを書いて分析データを眺められるということが大事なので、フロントエンドでSQLを生成するわけではなく、クエリ言語を定義するよりSQLを使えたほうが便利だったりするかもしれない。アクセス権限やSQLの検証など、いろいろ考えないといけないことはあるでしょうが、やる意味のあることかもしれません。

というか、たとえばbigqueryのようなものは、まさにそういうものとも言えますね。

0 コメント:

コメントを投稿