コンサートサービスを実装した後、データのエンコードとデコードの方法をカスタマイズしてAPIをレベルアップしたいかもしれません。バイナリフォーマットでのパフォーマンス向上、特別なデータ処理、異なるコンテンツタイプのサポートが必要な場合、このガイドでその実現方法を説明します!🚀
コンサートサービスには、最初からGoaの標準エンコーダーとデコーダーが装備されています。これらは最も一般的なフォーマットを処理します:
これは多くのアプリケーションで十分ですが、特定のニーズに合わせてカスタマイズする方法を見ていきましょう!
まず、現在のmain.go
サーバーセットアップを見てみましょう。これは異なるコンテンツタイプを処理するための重要な部分です:
func main() {
// ... サービスの初期化 ...
// デフォルトのエンコーダーとデコーダー
mux := goahttp.NewMuxer()
handler := genhttp.New(
endpoints,
mux,
goahttp.RequestDecoder, // デフォルトのリクエストデコーダー
goahttp.ResponseEncoder, // デフォルトのレスポンスエンコーダー
nil,
nil,
)
}
MessagePackサポートを追加してコンサートサービスをパワーアップしましょう!MessagePackはJSONよりも高速でコンパクトなバイナリフォーマットで、高性能APIに最適です。実装方法は以下の通りです:
package main
import (
"context"
"net/http"
"github.com/vmihailenco/msgpack/v5"
goahttp "goa.design/goa/v3/http"
"strings"
)
type (
// MessagePackエンコーダーの実装
msgpackEnc struct {
w http.ResponseWriter
}
// MessagePackデコーダーの実装
msgpackDec struct {
r *http.Request
}
)
// カスタムエンコーダーコンストラクタ - MessagePackエンコーダーを作成
func msgpackEncoder(ctx context.Context, w http.ResponseWriter) goahttp.Encoder {
return &msgpackEnc{w: w}
}
func (e *msgpackEnc) Encode(v any) error {
w.Header().Set("Content-Type", "application/msgpack")
return msgpack.NewEncoder(e.w).Encode(v)
}
// カスタムデコーダーコンストラクタ - 受信するMessagePackデータを処理
func msgpackDecoder(r *http.Request) goahttp.Decoder {
return &msgpackDec{r: r}
}
func (d *msgpackDec) Decode(v any) error {
return msgpack.NewDecoder(d.r.Body).Decode(v)
}
func main() {
// ... サービスの初期化 ...
// クライアントの要望(Acceptヘッダー)に基づくスマートなエンコーダー選択
encodeFunc := func(ctx context.Context, w http.ResponseWriter) goahttp.Encoder {
accept := ctx.Value(goahttp.AcceptTypeKey).(string)
// q値を含む複数のタイプを含むAcceptヘッダーを解析
// 例:「application/json;q=0.9,application/msgpack」
types := strings.Split(accept, ",")
for _, t := range types {
mt := strings.TrimSpace(strings.Split(t, ";")[0])
switch mt {
case "application/msgpack":
return msgpackEncoder(ctx, w)
case "application/json", "*/*":
return goahttp.ResponseEncoder(ctx, w)
}
}
// 迷ったときは、JSONが味方です!
return goahttp.ResponseEncoder(ctx, w)
}
// クライアントが送信するもの(Content-Type)に基づくスマートなデコーダー選択
decodeFunc := func(r *http.Request) goahttp.Decoder {
if r.Header.Get("Content-Type") == "application/msgpack" {
return msgpackDecoder(r)
}
return goahttp.RequestDecoder(r)
}
// カスタムエンコーダー/デコーダーを接続
handler := genhttp.New(
endpoints,
mux,
decodeFunc,
encodeFunc,
nil,
nil,
)
}
MessagePackサポートを追加したので、使い方を見てみましょう!以下はJSONとMessagePackの両方を使用する例です:
# お馴染みのJSONを使用してコンサートを作成
curl -X POST http://localhost:8080/concerts \
-H "Content-Type: application/json" \
-d '{"artist":"The Beatles","venue":"O2 Arena"}'
# MessagePack形式でコンサートを取得 - 高性能クライアントに最適!
curl http://localhost:8080/concerts/123 \
-H "Accept: application/msgpack" \
--output concert.msgpack
# MessagePackデータを使用してコンサートを作成
curl -X POST http://localhost:8080/concerts \
-H "Content-Type: application/msgpack" \
--data-binary @concert.msgpack
コンテンツネゴシエーションは、異なるクライアントのニーズに対応できる柔軟なAPIを構築する上で重要な側面です。効果的な実装方法は以下の通りです:
406 Not Acceptable
ステータスコードを返す特定のユースケースに基づいて適切なエンコーディング形式を選択します:
信頼性の高いデータ交換を確保するため、堅牢なエラー処理を実装します:
信頼性の高いエンコーディングとデコーディングを確保するため、包括的なテストを実装します:
Goaでのコンテンツネゴシエーションのカスタマイズ方法の詳細については、コンテンツネゴシエーションセクションを参照してください。
おめでとうございます!🎉 以下の方法を学びました:
コンサートAPIは、複数のフォーマットでデータ交換を処理できるようになり、より汎用的で高性能になりました。クライアントが簡単さを求めてJSONを好むか、速度を求めてMessagePackを好むかに関わらず、すべてに対応できます!
これでREST APIチュートリアルシリーズは完了です。カスタムエンコーディングサポートを備えた、本番環境で使用できる完全に機能するコンサートAPIが完成しました!