はじめに
アドベントカレンダー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にしました。
---- この辺りは変更なし
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を開くことができ、スキーマ、クエリを自動生成してくれていることがわかります。
以下のようなクエリを投げると、
{
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
}
}
}
↓レスポンス
{
"data": {
"product": {
"id": 1,
"tag": {
"id": 1,
"name": "果物"
},
"name": "りんご"
}
},
"errors": []
}
所感
- Hasuraと比べたメリットは現時点ではあまり感じられない?
- MutationやSubscriptionなど、ドキュメントに書かれていないことについても調べていきたい
- まだプレアルファ版なので、今後に期待!
- リリースのたびにテンションが上がるOSSなので、自分も貢献したい!
以上、雑記事かつ遅れてすみませんでした〜🙏