はじめに
今回は、Goの主要なWebフレームワーク、Gin, Fiber, Echo, Chiなどのフレームワークを土台とした、効率よくAPI開発ができる「Huma」というフレームワークについてまとめてみました。
本記事では、その魅力をサンプルコードを通じて深掘っていきます!
Humaとは?
Humaは、OpenAPI 3仕様を駆使してAPIを設計・構築するためのフレームワークです。まるで精巧な地図を手に冒険に出るように、計画的かつ効果的にAPIを構築していくことができます。
この、「Huma」というライブラリは最近伸びているらしく、そのスター数は驚異的なスピードで増加しています。
また、HumaはPythonのFastAPIのように、OpenAPI 3ベースのAPIを構築できます。Go言語でFastAPIのような快適な開発体験を求めるなら、Humaが最適な選択肢です。
Humaの魅力について
-
シンプルで直感的なAPI設計
- エンドポイントの定義やリクエスト/レスポンスのスキーマを、コード内で簡潔に記述することができます。また、Humaは他の有名なGoのWebフレームワーク(例えば、echo)と同様に直感的で使いやすい書き味を提供します
-
OpenAPI 3ベース
- OpenAPI 3仕様に準拠したAPIを定義することで、APIの構造化と標準化を促進します
HumaはPythonのFastAPIに強く影響を受けており、FastAPI同様にYAMLファイルを書くことなく、Goのコードから直接OpenAPIのYAMLを生成できます。
OpenAPIを生成するライブラリとしてswaggoが挙げられますが、swaggoはOpenAPI 2.0までの対応です。
HumaはGoのコードからOpenAPI3.1を生成でき、モダンなAPI開発ができると言えるでしょう。
- OpenAPI 3仕様に準拠したAPIを定義することで、APIの構造化と標準化を促進します
-
複数のフレームワークに対応
- Gin、Fiber、Echo、Chi などのフレームワークをルーターとして利用できます
これは、既存のフレームワークからの移行コストを最小限に抑えるための配慮であり、既存のコードベースに対しても少ない変更で導入が可能です。
- Gin、Fiber、Echo、Chi などのフレームワークをルーターとして利用できます
Humaはこんな開発者におすすめ
-
OpenAPI 3.1の対応
- 最新のOpenAPI仕様を活用したい場合に最適です
-
既存のフレームワークの活用
- chiやnet/httpを既に使用しており、追加の機能が必要な場合に便利です
-
自動ドキュメント生成
- コードから自動的にAPIドキュメントを生成したい場合に役立ちます
なお、chiを全面的にHumaに置き換えることは、状況によっては効率的でないかもしれません。しかし、chiとswaggoを使用していて、OpenAPI 2.0の制約に悩んでいる開発者にとって、Humaは強力な解決策となるでしょう。
実際に触ってみましょう
まずは、go get
でインストールしましょう。(Go 1.21以降が必要)
$ go get -u github.com/danielgtaylor/huma/v2
基本的なエンドポイントの作成
以下はシンプルなAPIサーバーの例です。
package main
import (
"context"
"net/http"
"github.com/danielgtaylor/huma/v2"
)
// レスポンス用の構造体を定義
type GreetingOutput struct {
Message string `json:"message"`
}
func main() {
// 新しいルータを作成
router := huma.New("My API", "1.0.0")
// GETエンドポイントを定義
router.Resource("/hello").Get("GetHello", "Returns a greeting")
Run(func(ctx context.Context, req *huma.Response) {
resp := GreetingOutput{Message: "Hello, World!"}
req.JSON(http.StatusOK, resp)
})
// サーバを起動
router.ListenAndServe(":8080")
}
-
router.Resource("/hello")
:リソースを定義 -
Get("GetHello", "Returns a greeting")
:GETメソッドのエンドポイントを作成 -
router.ListenAndServe(":8080")
:8080番ポートでサーバーを起動
Humaを使ったAPIサーバーの構築
package main
import (
"context"
"fmt"
"net/http"
"github.com/danielgtaylor/huma/v2"
"github.com/danielgtaylor/huma/v2/adapters/humachi"
"github.com/danielgtaylor/huma/v2/humacli"
"github.com/go-chi/chi/v5"
_ "github.com/danielgtaylor/huma/v2/formats/cbor"
)
// CLIオプションの定義。`--port`を指定するか、`SERVICE_PORT`環境変数を設定します。
type Options struct {
Port int `help:"リッスンするポート" short:"p" default:"8888"`
}
// GreetingOutputは挨拶操作のレスポンスを表します。
type GreetingOutput struct {
Body struct {
Message string `json:"message" example:"Hello, world!" doc:"挨拶メッセージ"`
}
}
func main() {
cli := humacli.New(func(hooks humacli.Hooks, options *Options) {
router := chi.NewMux()
api := humachi.New(router, huma.DefaultConfig("My API", "1.0.0"))
huma.Get(api, "/greeting/{name}", func(ctx context.Context, input *struct {
Name string `path:"name" maxLength:"30" example:"world" doc:"挨拶する名前"`
}) (*GreetingOutput, error) {
resp := &GreetingOutput{}
resp.Body.Message = fmt.Sprintf("Hello, %s!", input.Name)
return resp, nil
})
hooks.OnStart(func() {
http.ListenAndServe(fmt.Sprintf(":%d", options.Port), router)
})
})
cli.Run()
}
-
インポート部分
- 必要なパッケージをインポートします。特に、humaフレームワークとchiルーターが含まれています。また、CBORフォーマットを有効にするためのインポートもあります
-
CLIオプションの定義
- Options構造体でCLIオプションを定義しています。ここでは、リッスンするポート番号を指定します
-
レスポンスの構造体定義
- GreetingOutput構造体で、挨拶メッセージを返すレスポンスの形式を定義しています
-
メイン関数
-
humacli.NewでCLIアプリケーションを作成します
-
chi.NewMuxで新しいルーターを作成し、humachi.NewでHumaのAPIインスタンスを作成します
-
huma.Getで/greeting/{name}エンドポイントを定義し、Hello, {name}!というメッセージを返す処理を定義します
-
hooks.OnStartで、指定されたポートでサーバーを起動します
-
-
最後に、cli.RunでCLIを実行します
では、サーバーを起動させてプログラムを実行させましょう。
$ go run main.go
次は、curlコマンドでレスポンスを確認してみましょう。
$ curl http://localhost:8888/greeting/John
以下のJSONが帰ってきたらOKです!
{
"$schema":"http://localhost:8888/schemas/GreetingOutputBody.json",
"message":"Hello, John!"
}
OpenAPIの生成
サーバーを起動すると、/openapi.json
エンドポイントから自動的にOpenAPIドキュメントが取得できます。
curl http://localhost:8080/openapi.json
このJSONファイルをSwagger UIなどで読み込むことで、APIドキュメントを自動生成できます。
まとめ
Humaは、Go言語でのAPI開発を効率化し、モダンな開発体験を提供する強力なフレームワークです。
OpenAPI3仕様を基盤としたAPI開発のサポートや他のフレームワークとの高い互換性など、多くの魅力的な特徴を備えています!