焼売飯店

GoとかTS、JSとか

hono-middleware-goのご紹介

この記事はHono Advent Calendar 2025の2日目の記事です。

はじめに

皆さんはHonoのMiddlewareを書いたことがありますか?

HonoのドキュメントのCustom Middlewareから引用しますが、HonoのMiddlewareは非常にシンプルな仕組みで、以下のように app.use() に渡したコールバック関数内の、 await next() 呼び出しの前後でContextに対して処理を行うことができます。

// Custom logger
app.use(async (c, next) => {
  console.log(`[${c.req.method}] ${c.req.url}`)
  // ↑次のMiddleware / Handlerの処理の前に実行
  await next()
})

// Add a custom header
app.use('/message/*', async (c, next) => {
  await next()
  // ↓前のMiddleware / Handlerの処理の後に実行
  c.header('x-message', 'This is middleware!')
})

以下はHonoのドキュメントのModify the Response After Nextの例ですが、このように、Handlerが返したResponseをMiddlewareで上書きすることもできてしまいます。

const stripRes = createMiddleware(async (c, next) => {
  await next()
  c.res = undefined
  // Responseを上書き
  c.res = new Response('New Response')
})

このように、HonoのMiddlewareは、リクエスト / レスポンスの処理に介入して好きに加工を行える、大きな柔軟性を持っています。パッと見ただけでも、これなら何でもできそう!という印象になると思います。

ですが、ちょっと待ってください。

何でもできそうといっても、これはTypeScript / JavaScriptで書ける範囲なら何でもできそうという話のようにも見えます。

人によっては、Goの豊富なライブラリを使ってHonoのMiddlewareを書きたいことがあるかもしれないですよね!

そんなあなたのために、hono-middleware-goを紹介します!

github.com

続きを読む

macOSのApple Seatbelt (sandbox-exec) について調べた

先週金曜、突如OpenAIのCodex CLIというコーディングエージェントがリリースされましたが、このリポジトリを見て特に気になったのは、ツールの機能そのものよりも、以下の記述*1でした。

  • macOS 12+ – commands are wrapped with Apple Seatbelt (sandbox-exec).

    • Everything is placed in a read‑only jail except for a small set of writable roots ($PWD, $TMPDIR, ~/.codex, etc.). Outbound network is fully blocked by default – even if a child process tries to curl somewhere it will fail.

この記述によると、Codex CLIがmacOS上で起動するコマンドはApple Seatbelt (sandbox-exec) という機構でWrapされてSandbox化されるそうです。

本記事では、このApple Seatbeltについて調べた内容と、それを簡単に使うために実装したsbxというコマンドについて紹介します。

github.com

Apple Seatbeltとは?

Codex CLIの説明に当たり前のように現れた「Apple Seatbelt」ですが、これが何なのか筆者は全く知りませんでした。

ざっくり言うと、macOS組み込みの sandbox-exec というコマンドがあって、このコマンドを経由して別コマンドを実行すると、OSレベルでシステムへのアクセスをブロックできるというものです。 ブロックできる操作には、ファイルの読み書き、ネットワークアクセスなどがあります。

Apple Seatbeltそのものについての概要は、monochromeganeさんが言及していた*2以下のyuzuharaさんの記事を読んでいただくとイメージが掴みやすいと思います。

yuzuhara.hatenablog.jp

Apple Seatbeltは既に非推奨化されている

自分以外にも、Apple Seatbeltについて聞いたことが無かったという方も多いと思います。

それもそのはず、Apple Seatbeltは既に非推奨となっている機能で、代わりにApp Sandboxを使うようアナウンスされています。

それに加えて、Apple Seatbeltを使うための sandbox-exec コマンドの権限ポリシーの指定に使うSBPL (Sandbox Profile Language、あるいはSandbox Policy Language?) は仕様が公開されていません

内部的に sandbox-exec を使用しているChromiumのWikiには、「Apple-Sandbox-Guide-v1.0」と言うSBPLの仕様らしきドキュメントへのリンクが貼られていますが、なんと、これも第三者がリバースエンジニアリングしたもののようです。

https://reverse.put.as/wp-content/uploads/2011/09/Apple-Sandbox-Guide-v1.0.pdf

ということで、Apple Seatbeltは、

  • 非推奨化されている
  • そもそも仕様が公開されていない

ということから、知らなくて当然のものとわかりました。

この辺りの話は、今回自分が作ったコマンドの着想元となったlittledivyさんのsh-denoというツールに関する以下のブログにまとめられていて、ここを起点に情報を集めることができました。とても助かりました…。

Seatbelt Deno for macOS

あとは以下の記事も詳しいです。

macOS: App sandboxing via sandbox-exec · Karl Tarvas

sandbox-exec は、非推奨とはいえ、Chromium (Chrome) やBazelなどの重要なツールで使われているので、そう簡単に消えることはないと思われます。

続きを読む

Go 1.24で入ったGo製ツールの管理機能が便利だったのでおすすめしたい

Go 1.24の新機能で、Go製ツールのバージョンをGo Modulesで管理できるようになったので、その概要と便利なポイントを紹介していきます。

これまでのGo製ツールのバージョン管理について

これまで、Go製ツールのバージョンを管理する方法として標準的なものはありませんでした。

そのため、仕方なく直接 go install github.com/XXX/cmd/ツール名@バージョン をコマンドとして打たざるを得ないシーンが多々ありました。(過去の方法については今回あまり深堀りしません)

これからのGo製ツールのバージョン管理について

Go 1.24からGo組み込みの機能として提供される新しいツール管理方法は、従来のものよりずっと手軽になっています。

使い方が非常に簡単なので、ここで紹介する内容はGo以外のプロジェクトでも使えると思っています。Go Modulesを既存のプロジェクトに同居させる必要はありますが、それを特に気にしない方にはおすすめできます。

本記事では基本的な使い方についてのみ紹介します。詳しく知りたい方は以下のujiさんの記事などをご覧ください。(※ujiさんの記事執筆時点ではGo 1.24は未リリースでしたが、本記事の執筆時点ではリリース済みとなります)

zenn.dev

使い方

続きを読む

Shinyai.js 第1回 JavaScriptクイズの解答と解説

この記事は、syumai Advent Calendar 2024 18日目の記事です。

まずはクイズにチャレンジ!

今回のJavaScriptクイズにチャレンジできる特設ページを作ったので、まずはこちらで遊んでみてください。

Shinyai.js 第1回 JavaScriptクイズ - https://shinyaijs.syum.ai/events/1

v0にベースを作ってもらって、@opennextjs/cloudflareを使ってCloudflare Workersにデプロイする形でホストしています。

Shinyai.jsとは?

Shinyaigeekの家で行われた、ただの飲み会です。 何故か全員発表資料があったので、自分の持ってきたクイズに回答したり、それぞれのスライドを映したりしながら酒を飲んでいました。

準備不足だったために、当日に解説をちゃんと用意できていなかった問題もいくつかあったのですが、その場で一緒にECMAScriptの仕様を読んでくれたuhyoさんに非常に助けられました。ありがとうございます!

今回の問題

下記Zennのスクラップを資料としてクイズを行いました(上記特設ページおよび、本ブログと問題の内容は同じです)

zenn.dev

以下、解答と解説です。

もし不備があれば、ぜひXやブログのコメントでご連絡ください。

続きを読む

Goのtesting.TにContext()メソッドが追加されそうという話

この記事はsyumai Advent Calendar 2024の3日目の記事です。

火曜なので、本日は「Go」がテーマとなります。

(*testing.T).Context()とは

(*testing.T).Context() は、以下のProposalでAcceptされた、Goのテストで使用できる新しいメソッドです。

github.com

このメソッドから返却されるContextは、t.Cleanup() によって登録されたクリーンアップ関数が呼び出される直前にキャンセルされます。

Proposalの最終的なAPIは以下の通りです。

// Context returns a context that's cancelled just before
// [T.Cleanup]-registered functions are called.
//
// Cleanup functions can wait for any resources
// that shut down on Context.Done before the test completes.
func (t *T) Context() context.Context

実装は既にmaster branchにマージされていて、現在Go 1.24のマイルストーンでのリリースが見込まれています。 testing.Tへの追加と言いましたが、実際には、testing.T / B / Fで共通のインタフェースであるtesting.TBへ追加が行われたようです。

使い方

ProposalのDescriptionに記載されているのは、次のような使い方です。

func TestFoo(t *testing.T) {
    // 1. Contextを取得
    ctx := t.Context()
    // 2. WaitGroupを作成
    var wg sync.WaitGroup
    // 3. テストの完了時のクリーンアップ処理でwg.Waitを呼ぶように指定
    t.Cleanup(wg.Wait)
    // 4. WaitGroupにテスト内で使用する処理を登録
    wg.Add(1)
    go func() {
        defer wg.Done()
        // 5. テストのクリーンアップ処理の直前まで待つContextを渡す
        doSomething(ctx)
    }()
}

このコードを読むだけではあまりイメージしにくいかもしれませんが、本機能のメリットは「テストの完了まで待ってくれるContextが入手できる」点にあります。

上記の doSomething 関数をもっと具体化してみましょう。

続きを読む

Goで使える郵便番号検索ライブラリ「go-jpostcode」の紹介

この記事はsyumai Advent Calendar 2024の2日目の記事です。

月曜なので、本日は「これまで作ったツール・ライブラリ紹介」がテーマとなります。

本日のライブラリ

今回は、go-jpostcodeを紹介します。

github.com

go-jpostcodeとは?

go-jpostcodeは、郵便番号から住所を逆引きするのに使えるGoのライブラリです。

使い方

使い方は非常に単純で、 github.com/syumai/go-jpostcode をimportして、下記のように関数呼び出しを行ったらOKです。

// 住所を1件検索する
address, _ := jpostcode.Find("0010928")

// 住所を複数件検索する (郵便番号には、複数の住所が紐付くことがあるので)
addresses, _ := jpostcode.Search("1138654")

// JSONとして出力する
addressJSON, _ := address.ToJSON()
fmt.Println(addressJSON)

応用例

例えば、このライブラリを使って郵便番号検索APIを簡単に立ち上げることができます。

続きを読む

syumai Advent Calendar 2024のお知らせ

始まってしまった、12月が…。

ということで、syumai Advent Calendar 2024の開始をお知らせします。

adventar.org

これは何?

syumaiが25日間記事を出来る範囲で投稿し続けるAdvent Calendarです。

どうしてこうなった?

petamorikenさんの書く一人Advent Calendarが読みたい気持ちがありすぎたので、「morikenさんが一人Advent Calendarを書くなら自分も書く」と過去に勝手に発言していて、(全然morikenさん側のきっかけにはなってないと思いますが、)とても嬉しいことにmorikenさんのAdvent Calendarが開始したのを目撃したので、やるか…!となってます

方針

最近の持ちネタ量的に、1つのネタで25記事も書くのは厳しそうというのと、忙しさの波があるというのもあるので、なるべく負担にならない形でやっていこうと思います。

続きを読む