2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

GraphQL Meshを使ってMySQLのDBをGraphQLで操作してみる

Last updated at Posted at 2023-02-14

はじめに

GraphQL Meshとは複数のバックエンドサービスを束ねるGraphQLゲートウェイを構築するためのフレームワークです。GraphQL Mesh自体についての詳細は、数多くの記事が世の中にあるため省きます。

今回はGraphQL Meshを利用して、MySQLをラップしてGraphQLで扱う方法について試していきます。GraphQL Meshを経由して扱うことで、スキーマを自前で用意せずに既に存在するDB情報から自動で生成して取り扱うことができるようになります。

ローカルで動かすまでの手順

今回はローカルのdevサーバーとしてGraphQL Meshを立てて、任意のMySQLのDBを操作するところまで試します。

準備しておくもの

  • ローカルからアクセス可能なMySQLサーバー
    • 検証用に適当なデータベースとテーブルを作っておく
    • 今回はMySQL8.0を使っています

必要なパッケージのインストール

適当なディレクトリを作成し、その中に必要なパッケージをインストールします。

$ yarn add graphql @graphql-mesh/cli @graphql-mesh/mysql

.meshrc.ymlの作成

設定ファイルであるところの.meshrc.ymlを先程作ったディレクトリに追加して、内容を記述します。

.meshrc.yml
sources:
  - name: MySQL #任意のName
    handler:
      mysql:
        host: localhost #MySQLサーバーのホスト
        port: 3306 #ポート番号
        user: root #ユーザー名 今回は検証用にrootでアクセスする
        password: password #パスワード
        database: MyDatabase # 作成したDB名

handlermysqlとすることで、Meshが自動的にDBの定義を読み取り、DBの操作に必要なGraphQLのスキーマを用意してくれるようになります。この他にも、hostport等と並ぶところにtablestableFieldsを配列で記述することでアクセスできる領域をホワイトリスト形式で制限することができます。(残念ながら、読み取りのみ削除禁止などの細かい制限はできないようです。)

devサーバーの起動

GraphQL Meshのdevサーバーを起動します。

$ yarn mesh dev

実行すると、自動的にlocalhost:4000がブラウザで開かれ、GraphiQLが立ち上がります。
失敗する場合は、必要なパッケージがインストールされているか MySQLサーバーと疎通できているかあたりを確認してください。

image.png

スキーマの確認

Docsを見ると、接続したDBを操作するためのスキーマがいくつか用意されているのが確認できると思います。

序文でも書いた通り、これらのスキーマはDB接続時に自動的に生成されるため、GraphQL Mesh側で管理する必要がありません。

Queryを実行してみる

画面中央のフィールドにQueryを記述し、行を取得してみます。
余談ですが、公式ドキュメントではget${テーブル名}のような定義がされるように例が書かれているものの、実際はテーブル名だけの定義になっているようです。

{
  test_table(
    limit: 1,
    where: {
      id: "1"
    }
  ) {
    id
    name
    comment
  }
}

実行することで、目当ての行を取得することができました。
image.png

MySQLのようにlimitwhereが見られますが、まさにMySQLのクエリと同じ動きをしてくれます。公式ドキュメントによると、これらのGraphQLのスキーマは適切なMySQLのクエリに変換されて、DBに送信されます。上記の例でいうと、下記のクエリに変換されるようです。

SELECT id, name, comment FROM test_table
WHERE id = '1'
LIMIT 1;

基本的には用意されたスキーマに従って記述するだけで、MySQLのクエリと同じように行の取得が可能です。CodeSandboxにあげられているexampleを見る限り、JOIN句と同等の取得にも対応しているため、ある程度複雑な内容であっても対応できそうです。

Mutationを実行してみる

MySQLで言うところのUPDATE INSERT DELETEはMutationで行います。
テーブルごとにそれぞれの命令に相当するスキーマが定義されているため、必要に応じたスキーマを使う必要があります。

今回はUPDATEを実行します。

mutation update {
  update_test_table(test_table: {
    name: "updated",
    comment: "変更します"
  },
  where: {
    id: "1"
  }) {
    name
    comment
  }
}

実行することで、変更差分が返されます。
image.png

前段のQueryで再取得すると、内容の変更が確認できました。
image.png

Mutationに関しても、Queryと同様に用意されたスキーマに従って記述するだけでDBの操作を行うことができます。
INSERTDELETEも下記のように記述すれば実行できました。

INSERT
mutation insert {
  insert_test_table(test_table: {
    id: "2",
    name: "second",
    comment: "テスト"
  }) {
    id
    name
    comment
  }
}
DELETE
mutation delete {
  delete_test_table(
  where: {
    id: "2"
  })
}

懸念点

現時点では、いくつかの懸念点があると個人的に感じました。

  • 単体では、認可の仕組みを持てない。
    • 参照できるテーブルとカラム以外に関しては、これ単体では制御できないので、パブリックな場で公開するようなサービスで使う場合は誰に触られても良いような領域でしか使わない、もしくは別でそのあたりを制御する仕組みを用意する必要がありそうです。
  • INSERTがAUTO_INCREMENTに対応していない。
    • idをAUTO_INCREMENTかつNOT NULLにするというのはかなりよくあるケースだと思うのですが、insertのMutationを実行時にidが無指定だとエラーになって怒られてしまいます。ここは中々不便。
  • トランザクションが使えない。
    • 構造的に当然といえば当然ですが、トランザクションが使えないので複雑な更新処理などは難しいです。

まとめ

GraphQL Mesh経由でMySQLを操作する方法のご紹介でした。(MySQLをGraphQLでラップしたいというのも、それなりにニッチな需要な気がしますが、)実装とスキーマの管理不要で簡単に導入できるので、狭い領域や個人用であれば選択肢に挙げられる便利なツールだと思います。

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?