15
1

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 3 years have passed since last update.

SupabaseにGraphQLのエクステンションができたと聞いて🔥

Last updated at Posted at 2021-12-24

はじめに

アドベントカレンダー24日目です。クリスマスイブ!私はアドベントカレンダーの投稿が遅れているにも関わらず、朝の8時から呪術◯戦の映画を見てきました。
昨日の@nyaxの記事は、「自然言語処理の国際会議・論文探しのいろは
」という内容でした。私は就職活動を言い訳に、研究を全くしていないので耳が痛いですが、とても参考になりました!

これは

12月3日にSupabaseのブログに「pg_graphql: A GraphQL extension for PostgreSQL」という記事が投稿されました。
その記事によると、pg_graphqlはスキーマ生成、クエリパース、リゾルバのすべてをデータベースサーバに収めて、外部サービスを必要としないそうです。
しかも、pg_graphqlは既存のPostgreSQLスキーマを検査し、リゾルバにGraphQLスキーマを反映させてくれるらしいです。Hasuraみたいなイメージだと思います。
本記事では、プレアルファ版としてリリースされたpg_graphqlを試してみようと思います!

やってみる

Supabaseのエクステンションにはまだ追加されていなかったので、公式のQuickstartをポチポチして、dbサーバーをdockerで立ててやっていきます。せっかくなので、テーブルを作成する部分のコードを少しだけ書き換えてみます。
productテーブルは1つのtagを持っていて、tagテーブルは複数のproductを持っているというような1対Nの関係です。前回の記事ではN対Nの関係にしましたが、今回は簡単のため1対Nにしました。

dockerfiles/db/setup.sql
---- この辺りは変更なし
create role anon;
create extension if not exists "uuid-ossp";
create extension if not exists pg_graphql cascade;


grant usage on schema public to postgres, anon;
alter default privileges in schema public grant all on tables to postgres, anon;
alter default privileges in schema public grant all on functions to postgres, anon;
alter default privileges in schema public grant all on sequences to postgres, anon;

grant usage on schema graphql to postgres, anon;
grant all on function graphql.resolve to postgres, anon;

alter default privileges in schema graphql grant all on tables to postgres, anon;
alter default privileges in schema graphql grant all on functions to postgres, anon;
alter default privileges in schema graphql grant all on sequences to postgres, anon;


-- GraphQL Entrypoint
create function graphql("operationName" text default null, query text default null, variables jsonb default null)
    returns jsonb
    language sql
as $$
    select graphql.resolve(query, variables);
$$;

---- ここまで変更なし

create table tag(
    id serial primary key,
    name varchar(255) not null,
    created_at timestamp not null,
    updated_at timestamp not null
);

create table product(
    id serial primary key,
    name varchar(255) not null,
    created_at timestamp not null,
    updated_at timestamp not null,
    tag_id integer not null references tag(id)
);

-- insert data
insert into tag(name, created_at, updated_at)
values
    ('果物', now(), now()),
    ('', now(), now()),
    ('', now(), now());

insert into product(name, tag_id, created_at, updated_at)
values
    ('りんご', 1, now(), now()),
    ('みかん', 1, now(), now()),
    ('さば', 2, now(), now()),
    ('うに', 2, now(), now()),
    ('馬刺し', 3, now(), now());

上記のようにしてdocker compose upを実行し、http://localhost:4000/を開くと、GraphiQLのGUIを開くことができ、スキーマ、クエリを自動生成してくれていることがわかります。

query.png

以下のようなクエリを投げると、

{
  allTags {
    totalCount
    edges {
      node {
        id
        name
        products {
          edges {
            node {
              id
              name
	    }
	  }
	}
      }
    }
  }
}

こんな感じで返ってきます。

{
  "data": {
    "allTags": {
      "edges": [
        {
          "node": {
            "id": 1,
            "name": "果物",
            "products": {
              "edges": [
                {
                  "node": {
                    "id": 1,
                    "name": "りんご"
                  }
                },
                {
                  "node": {
                    "id": 2,
                    "name": "みかん"
                  }
                }
              ]
            }
          }
        },
        {
          "node": {
            "id": 2,
            "name": "魚",
            "products": {
              "edges": [
                {
                  "node": {
                    "id": 3,
                    "name": "さば"
                  }
                },
                {
                  "node": {
                    "id": 4,
                    "name": "うに"
                  }
                }
              ]
            }
          }
        },
        {
          "node": {
            "id": 3,
            "name": "肉",
            "products": {
              "edges": [
                {
                  "node": {
                    "id": 5,
                    "name": "馬刺し"
                  }
                }
              ]
            }
          }
        },
      ],
      "totalCount": 4
    }
  },
  "errors": []
}

ちなみに、productを一つ取得したい場合、自動生成されているドキュメントには、nodeIdを指定するように書かれていたり、ネストしているtagを取得するときにもnodeIdを指定するように書かれていて、実際にエディターに以下のクエリを入力すると怒られますが、レスポンスは想定したものが返ってきます。🤔

{
  product(id: 1) {
    id
    name
		tag {
			id
			name
		}
	}
}

↓怒られ

ang.png

↓レスポンス

{
  "data": {
    "product": {
      "id": 1,
      "tag": {
        "id": 1,
        "name": "果物"
      },
      "name": "りんご"
    }
  },
  "errors": []
}

所感

  • Hasuraと比べたメリットは現時点ではあまり感じられない?
  • MutationやSubscriptionなど、ドキュメントに書かれていないことについても調べていきたい
  • まだプレアルファ版なので、今後に期待!
  • リリースのたびにテンションが上がるOSSなので、自分も貢献したい!

以上、雑記事かつ遅れてすみませんでした〜🙏

15
1
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
15
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?