© 2023 NTT DATA Corporation
1日5分でPostgreSQLに詳しくなるアプリの開発
~PostgRESTを使ってみた~
2023/1/27 第38回 PostgreSQLアンカンファレンス@オンライン
株式会社NTTデータ 技術開発本部 石井愛弓
© 2023 NTT DATA Corporation 2
はじめに
© 2023 NTT DATA Corporation 3
今回のモチベーション
• PostgRESTを使ってみたい!
• モダンなフロントエンド(React)を書いてみたい!
さらに…
• PostgreSQLに詳しくなりたい!
• 英語の学習習慣をつけたい!
というモチベーションでwebアプリを実装しました!
名付けて「1日5分でPostgreSQLに詳しくなるアプリ just for myself」。
© 2023 NTT DATA Corporation 4
全体像
Reactで作成したwebアプリから、PostgRESTのAPIを呼び出す。
PostgRESTはPostgreSQLからデータを取得し、JSONレスポンスを返す。
PostgreSQL
PostgREST
React
API
JSON
SQL
レスポンス
© 2023 NTT DATA Corporation 5
PostgRESTの概要
© 2023 NTT DATA Corporation 6
PostgRESTとは
PostgreSQLのデータベースに対してRESTful APIの形式でアクセスできるようにするwebサー
バー。
例えば…ToDoテーブル
Id done task due
1 false 洗濯 null
2 false 掃除 null
3 false 料理 null
curl http://localhost:3000/todos
{“id”:1, “done”:false, “task”:”洗濯”, “due”:null},
{“id”:2, “done”:false, “task”:”掃除”, “due”:null},
{“id”:3, “done”:false, “task”:”料理”, “due”:null}
https://postgrest.org/en/stable/
© 2023 NTT DATA Corporation 7
一部の列だけを出力することも可能
カラムを指定しない場合はすべてのカラムを表示する
一部のカラムのみ取得したい場合は、selectを使う
例)peopleテーブルのfirst_nameカラムとageカラムだけ取得する
GET /people?select=first_name,age
[
{"first_name": "John", "age": 30},
{"first_name": "Jane", "age": 20}
]
取得する際に、リネームやキャストも可能
• :でリネーム
• GET /people?select=fullName:full_name,birthDate:birth_date
• ::でキャスト
• GET /people?select=full_name,salary::text
© 2023 NTT DATA Corporation 8
条件を使用して行を絞り込むことも可能
様々な演算子を利用できる
例)peopleテーブルの18歳以上の学生
• GET /people?age=gte.18&student=is.true
PostgreSQL
の場合
演算子
= eq
> gt
>= gte
< lt
<= lte
<> or != neq
LIKE like
ILIKE ilike
~ match
~* imatch
IN in
IS is
@@ fts
PostgreSQL
の場合
演算子
@> cs
<@ cd
&& ov
<< sl
>> sr
&< nxr
&> nxl
-|- adj
NOT not
OR or
AND and
さらに複雑なフィルタを使うために
は、ビューを作るか、ストアドプロ
シージャを使う必要がある。
© 2023 NTT DATA Corporation 9
JSON, JSONB
Jsonやjsonbのカラムの要素を取り出す、絞り込むことも可能
GET /people?select=id,json_data->blood_type&json_data->>blood_type=eq.A-
[
{ "id": 1, "blood_type": "A-" },
{ "id": 3, "blood_type": "A-" },
{ "id": 7, "blood_type": "A-" }
]
© 2023 NTT DATA Corporation 10
テーブルへのアクセス権限に応じて、APIを実行できる
APIの実行権限は、テーブルへのアクセス権限に対応する
例)PostgreSQLで参照のみ権限付与
→APIも参照のみ可能になる
→401 Unauthorizedのレスポンスになる
curl http://localhost:3000/todos -X POST ¥
-H "Content-Type: application/json" ¥
-d '{"task": "do bad thing"}'
grant select on api.todos to web_anon;
{
"hint": null,
"details": null,
"code": "42501",
"message": "permission denied for table todos"
}
© 2023 NTT DATA Corporation 11
データ型
様々なデータ型を扱うことができる。
これにより、now(timestamp型)やyes(bool型)などの特別な値も使用できる。
• Timestamp
• JSON
• Arrays
• Composite Types
• Ranges
• Bytea
• Hstore
• PostGIS
© 2023 NTT DATA Corporation 12
SQLとAPIの対応
SELECT : GET
INSERT : POST
UPDATE : PATCH
UPSERT : POST
DELETE : DELETE
curl "http://localhost:3000/people" ¥
-X POST -H "Content-Type: text/csv" ¥
--data-binary @- << EOF
name,age,height
J Doe,62,70
Jonas,10,55
EOF
curl "http://localhost:3000/employees" ¥
-X POST -H "Content-Type: application/json" ¥
-H "Prefer: resolution=merge-duplicates" ¥
-d @- << EOF
[
{ "id": 1, "name": "Old employee 1", "salary": 30000 },
{ "id": 2, "name": "Old employee 2", "salary": 42000 },
{ "id": 3, "name": "New employee 3", "salary": 50000 }
]
EOF
Bulk INSERT
UPSERT
curl "http://localhost:3000/table_name" ¥
-X POST -H "Content-Type: application/json" ¥
-d '{ "col1": "value1", "col2": "value2" }'
INSERT
© 2023 NTT DATA Corporation 13
インストール
© 2023 NTT DATA Corporation 14
PostgreSQL の準備
スキーマの作成
create schema api;
テーブルの作成
create table api.todos (
id serial primary key,
done boolean not null default false,
task text not null,
due timestamptz
);
データの挿入
insert into api.todos (task) values
('finish tutorial 0'), ('pat self on back');
ロールの作成
create role web_anon nologin;
grant usage on schema api to web_anon;
grant select on api.todos to web_anon;
ログイン用ロールの作成
create role authenticator noinherit login password
'mysecretpassword';
grant web_anon to authenticator;
© 2023 NTT DATA Corporation 15
PostgREST インストール
• githubのリリースページからバイナリをダウンロード(最新版はv10.1.1)
• https://github.com/PostgREST/postgrest/releases/tag/v10.1.1
• 設定ファイルを準備(test.conf)
• 起動
• ./postgrest test.conf
→これだけでOK!
curl http://localhost:3000/todos でレスポンスが返ってくる!
db-uri = "postgres://authenticator:mysecretpassword@localhost:5432/postgres"
db-schemas = "api"
db-anon-role = "web_anon"
© 2023 NTT DATA Corporation 16
アプリを作ってみる
© 2023 NTT DATA Corporation 17
どんなアプリ?
PostgreSQLのリリースノートを1日1個理解していくためのアプリ。Just for myself
「理解した」「とりあえず読んだ」「また今度読む」を押していく
© 2023 NTT DATA Corporation 18
デモ
© 2023 NTT DATA Corporation 19
おまけ機能1:何度もとりあえず読む
エビングハウスの忘却曲線をヒントに、繰り返し学習する。
短期記憶はすぐに忘れるので、繰り返すこ
とで長期記憶になる
※今回は覚えるというより理解することが
目的なので、記憶の問題ではない。が、や
はり、繰り返すことで、理解が進む側面も
あるのではないか、と考えたので参考にした。
「理解した」ものはもう表示しない
「とりあえず読んだ」項目については翌日
も表示して理解できるまで何度も出会う
「また今度読む」は三日後にまた表示する
bは節約率(%)、tは時間(分)
© 2023 NTT DATA Corporation 20
ノートテーブルの次の出現スケジュール(next_date)を更新
次の出現スケジュール(next_date) が 今日の日付 または 今日より前 の件数が今日のノルマ
↑
NULL
↑
+3日
↑
+1日
GET /releasenotes?next_date=lte.today&limit=1
PATCH /releasenotes?id=eq.1 -d '{ "next_date": null }
© 2023 NTT DATA Corporation 21
おまけ機能2:代わりに読んで~
英語を読む気力がないときも、読み上げた英語を聴くだけならハードルが下がる?と考え採用
無料APIのWeb Speech APIを使って英語を読み上げ
※デモあり
© 2023 NTT DATA Corporation
その他、記載されている会社名、商品名、又はサービス名は、
各社の登録商標又は商標です。

1日5分でPostgreSQLに詳しくなるアプリの開発 ~PostgRESTを使ってみた~(第38回PostgreSQLアンカンファレンス@オンライン 発表資料)

  • 1.
    © 2023 NTTDATA Corporation 1日5分でPostgreSQLに詳しくなるアプリの開発 ~PostgRESTを使ってみた~ 2023/1/27 第38回 PostgreSQLアンカンファレンス@オンライン 株式会社NTTデータ 技術開発本部 石井愛弓
  • 2.
    © 2023 NTTDATA Corporation 2 はじめに
  • 3.
    © 2023 NTTDATA Corporation 3 今回のモチベーション • PostgRESTを使ってみたい! • モダンなフロントエンド(React)を書いてみたい! さらに… • PostgreSQLに詳しくなりたい! • 英語の学習習慣をつけたい! というモチベーションでwebアプリを実装しました! 名付けて「1日5分でPostgreSQLに詳しくなるアプリ just for myself」。
  • 4.
    © 2023 NTTDATA Corporation 4 全体像 Reactで作成したwebアプリから、PostgRESTのAPIを呼び出す。 PostgRESTはPostgreSQLからデータを取得し、JSONレスポンスを返す。 PostgreSQL PostgREST React API JSON SQL レスポンス
  • 5.
    © 2023 NTTDATA Corporation 5 PostgRESTの概要
  • 6.
    © 2023 NTTDATA Corporation 6 PostgRESTとは PostgreSQLのデータベースに対してRESTful APIの形式でアクセスできるようにするwebサー バー。 例えば…ToDoテーブル Id done task due 1 false 洗濯 null 2 false 掃除 null 3 false 料理 null curl http://localhost:3000/todos {“id”:1, “done”:false, “task”:”洗濯”, “due”:null}, {“id”:2, “done”:false, “task”:”掃除”, “due”:null}, {“id”:3, “done”:false, “task”:”料理”, “due”:null} https://postgrest.org/en/stable/
  • 7.
    © 2023 NTTDATA Corporation 7 一部の列だけを出力することも可能 カラムを指定しない場合はすべてのカラムを表示する 一部のカラムのみ取得したい場合は、selectを使う 例)peopleテーブルのfirst_nameカラムとageカラムだけ取得する GET /people?select=first_name,age [ {"first_name": "John", "age": 30}, {"first_name": "Jane", "age": 20} ] 取得する際に、リネームやキャストも可能 • :でリネーム • GET /people?select=fullName:full_name,birthDate:birth_date • ::でキャスト • GET /people?select=full_name,salary::text
  • 8.
    © 2023 NTTDATA Corporation 8 条件を使用して行を絞り込むことも可能 様々な演算子を利用できる 例)peopleテーブルの18歳以上の学生 • GET /people?age=gte.18&student=is.true PostgreSQL の場合 演算子 = eq > gt >= gte < lt <= lte <> or != neq LIKE like ILIKE ilike ~ match ~* imatch IN in IS is @@ fts PostgreSQL の場合 演算子 @> cs <@ cd && ov << sl >> sr &< nxr &> nxl -|- adj NOT not OR or AND and さらに複雑なフィルタを使うために は、ビューを作るか、ストアドプロ シージャを使う必要がある。
  • 9.
    © 2023 NTTDATA Corporation 9 JSON, JSONB Jsonやjsonbのカラムの要素を取り出す、絞り込むことも可能 GET /people?select=id,json_data->blood_type&json_data->>blood_type=eq.A- [ { "id": 1, "blood_type": "A-" }, { "id": 3, "blood_type": "A-" }, { "id": 7, "blood_type": "A-" } ]
  • 10.
    © 2023 NTTDATA Corporation 10 テーブルへのアクセス権限に応じて、APIを実行できる APIの実行権限は、テーブルへのアクセス権限に対応する 例)PostgreSQLで参照のみ権限付与 →APIも参照のみ可能になる →401 Unauthorizedのレスポンスになる curl http://localhost:3000/todos -X POST ¥ -H "Content-Type: application/json" ¥ -d '{"task": "do bad thing"}' grant select on api.todos to web_anon; { "hint": null, "details": null, "code": "42501", "message": "permission denied for table todos" }
  • 11.
    © 2023 NTTDATA Corporation 11 データ型 様々なデータ型を扱うことができる。 これにより、now(timestamp型)やyes(bool型)などの特別な値も使用できる。 • Timestamp • JSON • Arrays • Composite Types • Ranges • Bytea • Hstore • PostGIS
  • 12.
    © 2023 NTTDATA Corporation 12 SQLとAPIの対応 SELECT : GET INSERT : POST UPDATE : PATCH UPSERT : POST DELETE : DELETE curl "http://localhost:3000/people" ¥ -X POST -H "Content-Type: text/csv" ¥ --data-binary @- << EOF name,age,height J Doe,62,70 Jonas,10,55 EOF curl "http://localhost:3000/employees" ¥ -X POST -H "Content-Type: application/json" ¥ -H "Prefer: resolution=merge-duplicates" ¥ -d @- << EOF [ { "id": 1, "name": "Old employee 1", "salary": 30000 }, { "id": 2, "name": "Old employee 2", "salary": 42000 }, { "id": 3, "name": "New employee 3", "salary": 50000 } ] EOF Bulk INSERT UPSERT curl "http://localhost:3000/table_name" ¥ -X POST -H "Content-Type: application/json" ¥ -d '{ "col1": "value1", "col2": "value2" }' INSERT
  • 13.
    © 2023 NTTDATA Corporation 13 インストール
  • 14.
    © 2023 NTTDATA Corporation 14 PostgreSQL の準備 スキーマの作成 create schema api; テーブルの作成 create table api.todos ( id serial primary key, done boolean not null default false, task text not null, due timestamptz ); データの挿入 insert into api.todos (task) values ('finish tutorial 0'), ('pat self on back'); ロールの作成 create role web_anon nologin; grant usage on schema api to web_anon; grant select on api.todos to web_anon; ログイン用ロールの作成 create role authenticator noinherit login password 'mysecretpassword'; grant web_anon to authenticator;
  • 15.
    © 2023 NTTDATA Corporation 15 PostgREST インストール • githubのリリースページからバイナリをダウンロード(最新版はv10.1.1) • https://github.com/PostgREST/postgrest/releases/tag/v10.1.1 • 設定ファイルを準備(test.conf) • 起動 • ./postgrest test.conf →これだけでOK! curl http://localhost:3000/todos でレスポンスが返ってくる! db-uri = "postgres://authenticator:mysecretpassword@localhost:5432/postgres" db-schemas = "api" db-anon-role = "web_anon"
  • 16.
    © 2023 NTTDATA Corporation 16 アプリを作ってみる
  • 17.
    © 2023 NTTDATA Corporation 17 どんなアプリ? PostgreSQLのリリースノートを1日1個理解していくためのアプリ。Just for myself 「理解した」「とりあえず読んだ」「また今度読む」を押していく
  • 18.
    © 2023 NTTDATA Corporation 18 デモ
  • 19.
    © 2023 NTTDATA Corporation 19 おまけ機能1:何度もとりあえず読む エビングハウスの忘却曲線をヒントに、繰り返し学習する。 短期記憶はすぐに忘れるので、繰り返すこ とで長期記憶になる ※今回は覚えるというより理解することが 目的なので、記憶の問題ではない。が、や はり、繰り返すことで、理解が進む側面も あるのではないか、と考えたので参考にした。 「理解した」ものはもう表示しない 「とりあえず読んだ」項目については翌日 も表示して理解できるまで何度も出会う 「また今度読む」は三日後にまた表示する bは節約率(%)、tは時間(分)
  • 20.
    © 2023 NTTDATA Corporation 20 ノートテーブルの次の出現スケジュール(next_date)を更新 次の出現スケジュール(next_date) が 今日の日付 または 今日より前 の件数が今日のノルマ ↑ NULL ↑ +3日 ↑ +1日 GET /releasenotes?next_date=lte.today&limit=1 PATCH /releasenotes?id=eq.1 -d '{ "next_date": null }
  • 21.
    © 2023 NTTDATA Corporation 21 おまけ機能2:代わりに読んで~ 英語を読む気力がないときも、読み上げた英語を聴くだけならハードルが下がる?と考え採用 無料APIのWeb Speech APIを使って英語を読み上げ ※デモあり
  • 22.
    © 2023 NTTDATA Corporation その他、記載されている会社名、商品名、又はサービス名は、 各社の登録商標又は商標です。