Go の Firestore SDK で消える項目と通らない値

結論 Go の Firestore SDK は、struct とドキュメントの間で項目を消しても、読み飛ばしてもエラーを返さない 書く側: Set は文書を丸ごと置き換える。serverTimestamp の項目は非ゼロだと書かれないので、読んで詰め直した Set で作成日時が消える。MergeAll は map 専用で、map の中の struct は丸ごと置き換わる。omitempty は false / 0 / ゼロ時刻を消し、struct は消さない 読む側: DataTo は struct に無いキーを捨てる。null を string や int に読んでも何もしない。int には整数で表せる double は入り、文字列は入らない 通らない値: ID・日時・クエリの値の規則を、SDK は一部しか検査しない。ID の規則違反は読みと書きで違うエラーになり、不正な UTF-8 を where に渡すと期限まで返ってこない 書き込みの経路ごとに、エミュレータで実際の文書を読んで確かめる 以下は cloud.google.com/go/firestore v1.26.0 / Firestore エミュレータ v1.22.0 / Go 1.26.4 で実測した。 本番の Firestore では試していない。 前提: 書き込み API ごとに書く範囲が違う ...

2026-10-03 ·  2026-10-03 · 7 分 · 1463 文字

Go の JSON が警告なしに潰す null と欠落

結論 JSON の「キー欠落」「null」「[]」「0」を、Go の型は全部は区別できない。encoding/json は区別が消えてもエラーを返さない 書く側: nil スライスは null になる。*T に omitempty を付けると null を出せない。同じ階層に同じタグがあると両方消える。NaN が 1 つあると Marshal そのものが失敗する 読む側: キーは大文字小文字を無視して照合し、構造体に無いキーは捨てる。null はポインタ・スライス・map・interface 以外には何もしない。値型は 0 と欠落を、ポインタは null と欠落を区別できない 区別が契約なら、型に頼らず map[string]json.RawMessage でキー単位に見る。テストも構造体ではなく生の JSON で固定する 以下は Go 1.26.4 / testify v1.12.1 / go-playground/validator v10.30.5 で実測した。 前提: 区別を持てるのは Go の型の側だけ JSON の 1 項目は「キーが無い」「null」「空 ([] / "")」「ゼロ (0 / false)」「値あり」のどれかになる。 Go の値型が持てる状態は「ゼロ値」か「値あり」の 2 つで、ポインタ・スライス・map は nil の分だけ 1 つ増える。 JSON 側の状態を Go の型へ写すと、どこかの区別が消える。 ...

2026-10-01 ·  2026-10-01 · 5 分 · 1027 文字

RedoclyでOpenAPIをタグ分割する方法

結論:RedoclyでOpenAPI Specをタグで分割できる Redocly CLIのfilter-in/filter-outデコレーターを使えば、1つのOpenAPI定義を複数のドキュメントに分割できる。 公開API用と管理API用でSwagger UIを分けたい場合など、タグベースでAPI仕様を分離できる。 背景:なぜ分割が必要か 単一のGo APIで複数のクライアント向けにエンドポイントを提供する場合、全エンドポイントを1つのSwagger UIに表示すると見づらい。 例: 公開API: ユーザー機能、コンテンツ表示 管理API: データ管理、レポート取得、設定変更 → それぞれ専用のSwagger UIを生成したい 解決方法:Redocly CLI + filter デコレーター 1. swagでOpenAPI定義を生成 swag: @echo "==> Running swag init" >&2 @swag init -g cmd/your-api/main.go -o docs @npx -y @redocly/cli@latest bundle docs/swagger.yaml --config docs/redocly-public.yaml -o docs/swagger_public.yaml @npx -y @redocly/cli@latest bundle docs/swagger.yaml --config docs/redocly-admin.yaml -o docs/swagger_admin.yaml && \ sed -i -e 's,API for Public,API for Admin,g' docs/swagger_admin.yaml 2. 公開API用設定:管理タグを除外 docs/redocly-public.yaml: ...

2026-01-17 ·  2026-01-17 · 1 分 · 156 文字

Go言語omitemptyの罠:falseが保存できない

結論:omitemptyは便利だが罠がある omitemptyタグは空値を省略できて便利だが、falseや0が保存できなくなる罠がある。 特にboolean型で**「false」と「未設定」を区別したい場合は要注意**だ。 omitemptyとは 空値の場合にフィールドを省略するタグ。JSON/Firestoreへの保存時にデータサイズを削減できる。 type User struct { Name string `json:"name"` Email string `json:"email,omitempty"` // 空なら省略 } ⚠️ 最大の罠:「空」とみなされる値 以下の値は「空」として扱われ、omitempty付きフィールドから消える: 型 空とみなされる値 保存できない値の例 真偽値 false ❌ falseが保存不可 数値 0 ❌ 0が保存不可 文字列 "" ❌ 空文字列が保存不可 スライス/マップ nil または長さ0 ❌ 空配列が保存不可 ポインタ nil - time.Timeのゼロ値は、JSONでは「空」に当たらず消えない。下の「struct と time.Time は omitempty で消えない」を参照。 実例:boolean型の罠 問題のあるコード type Config struct { EnableFeature bool `firestore:"enableFeature,omitempty"` } config := Config{EnableFeature: false} // ❌ Firestoreに保存されない! // "enableFeature"フィールド自体が消える これでは「false」と「未設定」が区別できない。 ...

2025-10-27 ·  2026-10-03 · 2 分 · 372 文字

コンテナ内でのみ golangci-lint 実行時に 'error obtaining VCS status: exit status 128' エラーが発生する問題

問題 golangci-lint をコンテナ内で実施すると以下エラーが発生した コンテナ内でのみ発生して、ホストで実行すると発生しなかった WARN [runner] Can't process results by diff processor: can't prepare diff by revgrep: no version control repository found cmd/main.go:1: : error obtaining VCS status: exit status 128 Use -buildvcs=false to disable VCS stamping. (typecheck) 原因 golangci-lint は git の情報を取得しようとするが、コンテナ内の 作業ディレクトリが git の安全なディレクトリとして登録されていないために発生する 解決方法 以下 .gitconfig を作成して、compose.yaml で /root/.gitconfig:ro でマウントした [safe] directory = /work # コンテナ内の作業ディレクトリを指定 directory = /work/api # コンテナ内の作業ディレクトリを指定

2025-09-17 ·  2025-09-17 · 1 分 · 64 文字