supabase、すごくいい

## supabaseって何？
[公式ページ](https://supabase.com/)から。

> Supabase is an open source Firebase alternative for building secure and performant Postgres backends with minimal configuration.

Firebaseの代替Open Sourceで、Postgresを使ってます、という感じですね。
[githubのREADME上のstatus](https://github.com/supabase/supabase#status)はPublic Betaまでチェックが入っていて、商用利用以外は十分耐えるよという形になっています。

### Firebaseとどの辺が違うの？
大きく違う点としては以下の内容を挙げることができます。

1. DBがNoSQLじゃなくて、Postgres
1. Hostingはない
1. serverless functionのランタイムがDeno

個人的にはPosgresなのが良い印象です（無料でリレーショナルデータベースが使えるサービスってなかなかないので...）。
Hostingについては、強力なhosting serviceが他にもたくさんあるのでなくても困らないかなと思っています。
Denoである点について、私はsupabaseを触るまでDenoを触ったことがなかったのですが、書き心地としては基本Nodeと同じであまり違和感はありませんでした。DenoとNodeの違いなどについてはこの記事の範囲を超えるので割愛します。

### お値段感

詳細は[こちら](
https://supabase.com/pricing)をご参照。フリープランだとDBが500MB、Storageが1GB、functionが500,000呼び出しまでとなっています。小規模なサービスだと余裕、広く使ってもらうとなるとProプランの検討が必要になりそうですね。

## どの辺がいいの？

現状使っている感覚としてFirebaseより良いなと思っている点としては以下の内容を挙げることができます。

1. CLIコマンドの機能が充実している
1. DBのスキーマから自動でREST/GraphQLのAPIを生成してくれる

### 1. CLIコマンドの機能が充実している

#### 環境構築
`supabase init`でローカル用の設定ファイル等々を配置してくれます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/619165/41a45f44-ef6b-5235-229a-4f13cb0cc939.png)

生成されたディレクトリ・ファイルは以下のようになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/619165/a514632e-52d9-b83b-e6b2-07897c8a8ac3.png)

`seed.sql`はローカルのDBに対して起動時にやりたい処理をかけます（テストデータを入れるなど）。
`functions`はserverless functionのコードなどが入ります。

`supabase start`でDockerを利用したsupabase環境を構築してくれます。
※めっちゃDockerのイメージをpullするので注意
pullして諸々起動し終わるとコンソール上に一通り接続情報が表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/619165/19c80cb7-3d40-19e6-3934-e340cf7c7461.png)

例えばStudio URLをブラウザで表示すると、supabaseのdashboardが表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/619165/b3afe19a-128f-c004-d237-b6cdebee620c.png)

#### serverless function

`supabase functions new [function-name]`で関数を生成できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/619165/ad6638c4-8bdf-c232-bcdc-c70776e3fd51.png)

生成されたhello-world/index.tsはこんな感じです。呼び出し方も書いてますね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/619165/112c64a6-c945-f471-2bbb-a70cca673817.png)

実際に呼び出すとこんな感じです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/619165/2eadfbc2-f0f9-e9a3-4b00-3195f3d28154.png)

ログを流したいときは`supabase functions serve`でserveします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/619165/4475b51f-f138-b852-c737-5380b7f50889.png)

デプロイは`supabase functions deploy [function-name]`です。

#### DB

ローカルのスキーマ変更を吐き出してリモートにプッシュする

例えば、ローカルのStudioからuserテーブルを作りました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/619165/a7fcc2ce-bd7a-9ec8-f69a-9bcfd6df50fc.png)

`supabase db diff -f [filename-suffix]`でスキーマの差分を吐き出すことができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/619165/6485636d-1341-1dac-59c8-af6941bacec4.png)

リモートにこのスキーマをプッシュしたいときは`supabase login`と`supabase link`コマンドで特定のprojectとlinkしたうえで、以下のコマンドを叩きます。

`supabase db push`でリモートにプッシュします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/619165/2bd6bf90-bac3-6dc4-dc01-bfbf13da2ba4.png)

`suapbase db remote commit`でリモート側のスキーマ差分をsqlに吐き出すこともできます。

#### TypeScriptの型定義ファイル

`supabase gen types typescript`でDBのスキーマからTypeScriptの型定義ファイルを生成できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/619165/d510b604-b17d-f0fe-1131-dfb0b0ea3c4d.png)

生成したファイルはこんな感じです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/619165/c2065d3d-464f-6c6e-9419-33b72416ea00.png)

これはsupabaseのsdkに噛ませることもできるため、型安全に開発を進めることができます。

DBのスキーマを云々、型定義を云々についてはFirebaseではできないので（そもそもNoSQLでスキーマレスだし…）、個人的にかなり強力な強みかなと思っています。

### 2.DBのスキーマから自動でREST/GraphQLのAPIを生成してくれる

DBのスキーマに従って自動でREST/GraphQLのAPIを生成してくれます（PostgRESTを使っているらしい）。GUI上で呼び出し方のドキュメントを確認することができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/619165/184af987-3e28-d4fe-5435-68dae1e95ebd.png)

## Tips

### sdk経由で複雑なクエリを呼び出したい場合

[外部キーなどを貼っている場合はsdkでもよしなに結合してくれる](https://supabase.com/docs/guides/api/joins-and-nesting)のですが、そうでない副問い合わせを含むクエリなどはsdkでは表現できない場合があります。この場合はsqlをviewとしてDB側に定義しておいて、それをsdkで呼び出すようにしています。（viewの型定義は`supabase gen`で生成できるため)