😺

[Flutter]Hono✖️Supabaseでアプリを作る- Get -

2025/03/03に公開

HonoとSupabaseでアプリを作った話

触れる話
Honoの基本、CRUD操作とFlutterの実装
触れない話
デプロイの仕方
FlutterでのAPI秘匿化

普段はFlutterの開発がメインなのですがTypeScriptに入門し自分のメインのフレームワークであるFlutterと連携して作成したいなと思いAPIを簡単に作成でき、最近注目のフレームワークを使った開発がしたくて今回作成しました。
サーバーはSupabaseを使用し、honoでCRUD操作を行います。フロントエンドは普段から使用しているFlutterでGitHubからCloudFrearにデプロイする形で実装していきます。

Honoの実装

Honoの実装は非常にシンプルです。

import { Hono } from 'hono'
import { cors } from 'hono/cors';

const app = new Hono()

app.use(
  '*',
  cors({
    origin: '*',
    allowMethods: ['GET', 'POST', 'PUT', 'DELETE'],
    allowHeaders: ['Content-Type', 'Authorization'],
    maxAge: 600,
  })
);

app.get('/',async (c) => {
  return c.json({msg:'hello'})
})

export default app

これでデプロイしてhttp://~~~~/ にアクセスすると

{
    msg:'hello'
}

が確認できると思います。次にSupabaseにアクセスしてkeyを入手します。
入手したkeyをルートディレクトリに.dev.vars という名前のファイルを作成します。
作成したファイルに以下の形でURLとanonkeyを記述してください。

SUPABASE_URL=http://~~~.supabase.co
SUPABASE_API_KEY=~~~~

Honoは.dev.vars でdotenvなどを仲介せずにc.で環境変数にアクセスできます。

index.ts
const SUPABASE_URL = (c.env as { SUPABASE_URL: string }).SUPABASE_URL;
const SUPABASE_API_KEY = (c.env as { SUPABASE_API_KEY: string }).SUPABASE_API_KEY;

データの取得(Get)

今回私は取得関数を作成し、結果をリスト化、app.getでjsonで返すように指定して作成しました。

export async function fetchData(
    SUPABASE_URL: string,
    SUPABASE_API_KEY: string,
    queryword:string,
  ) {
    const supabase = createClient(SUPABASE_URL, SUPABASE_API_KEY);
  
    try {
      //データベースの[queryword]と同じカラムの値をすべて取ってくる
      const { data, error } = await supabase.from(queryword).select('*');
      if (error) {
        console.error('Supabase error:', error);
        throw error;
      }
      // created_atの値を取得する
      return data.map((data) => data.created_at);
    } catch (error) {
      console.error('Error fetching user names:', error);
      return 'エラーが発生しました';
    }
  }
  
index.ts
app.get('/',async (c) => {
  const SUPABASE_URL = (c.env as { SUPABASE_URL: string }).SUPABASE_URL;
  const SUPABASE_API_KEY = (c.env as { SUPABASE_API_KEY: string })
    .SUPABASE_API_KEY;
  const datas = await fetchData(SUPABASE_URL, SUPABASE_API_KEY,'test');
  
  return c.json({getData:datas})
})

これでデプロイしてhttps://~~~/にアクセスすればSupabaseのtestというカラムのデータをすべて取ってくるようになりこの場合リスト型でSupabaseのtestカラムにあるcreated_atの値を返します。

{
  "data": [
    "2025-02-05T05:24:07.632983+00:00",
    "2025-02-06T04:59:59.985928+00:00"
  ]
}

ここまでできたらGet型は終了です。

Flutter

Flutterでは作成したAPIにアクセスしていく実装を行います。

  final String api = dotenv.env['API_KEY']!;
  List<dynamic> createdAt = [];
  String msg = "";

void fetchData() async {
    final response = await http.get(Uri.parse(api));
    final responseDB = await http.get(Uri.parse('${api}'));
    if (response.statusCode == 200) {
      setState(() {
        createdAt = json.decode(utf8.decode(responseDB.bodyBytes))['data'];
      });
    } else {
      setState(() {
        msg = 'Failed to load data';
      });
    }
  }

あとはListViewでcreatedAtリストの中身を表示すれば取得する部分は完成です。

まとめ

Honoは意外と簡単に実装できることがわかったかと思います。Get型は以上です。
FluterというよりはSupabaseとHonoという実装の話をメインにしました。FlutterでのAPI実装については丁寧な記事が他の方が書かれていると思うのでそちらを参照してください(笑)。
これらを踏まえてFlutterの実装ではテスト実装を想定しています。本番環境ではriverpod等を使用することが多いと思いますのでそちらの実装に合わせてみると良いと思います。

Discussion