ADR 001 — ワイヤフォーマットとしてのProtobuf
ステータス: 受理済み — 実装は延期
日付: 2026-04
更新(2026-06)
本番のワイヤフォーマットは 署名付きrawストリング を伴う JSON です; .proto スキーマは存在しますがコード生成は稼働していません。Protobufは引き続き目標の正規フォーマットであり、イベントログとともに入ります — JSONは現行ファームウェア世代のためにサポートされ続けます。
文脈
Raiznetは、ESP32ファームウェア(C++、メモリ制約)とNode.jsサーバー(TypeScript)の両方で動くシリアライズ形式を必要とします。形式はコンパクトで、スキーマで強制され、2つの大きく異なるランタイムで保守可能でなければなりません。
評価した候補:
| 形式 | Node.js | ESP32 | スキーマ | バイナリ |
|---|---|---|---|---|
| JSON | ネイティブ | ArduinoJson | なし | なし |
| MessagePack | msgpackr | msgpack-c | なし | あり |
| CBOR | cbor-x | tinycbor | なし | あり |
| Protobuf | @bufbuild/protobuf | nanopb | あり | あり |
決定
Protobuf(Protocol Buffers v3) を、次とともに:
- Node.jsでは
@bufbuild/protobuf+@bufbuild/protoc-gen-es - ESP32では
nanopb
.proto スキーマは packages/protocol/proto/ にあり、両ランタイムで共有されます。TypeScriptコードはビルド時に protoc-gen-es で生成されます。
根拠
- 共有スキーマ: 1つの
.protoファイルが唯一のソースオブトゥルース。スキーマの変更は両側の生成コードに反映されます — 手作業のstructはありません。 - バイナリのコンパクトさ: JSONより小さなパケット。Wi-Fiで送るバッテリー駆動のESP32にとって重要です。
- 型安全性: 生成されたTypeScript型は正確で、手動パースの必要をなくします。
- nanopbの成熟度: 組み込みC向けのよく確立されたProtobuf実装で、動的メモリ割り当てがなく、ESP32の制約内で動きます。
- フィールド番号の安定性: Protobufの前方/後方互換性の保証により、古いファームウェアで動く既存ノードを壊さずにスキーマを進化させられます。
トレードオフ
- Protobufは人間が読めません。生パケットのデバッグにはデコーダが必要です。
- nanopbはコンパイル時に繰り返しフィールドと文字列フィールドの最大サイズを定義する必要があります。
- 新しいセンサー型の追加には、
.protoファイルの更新、コードの再生成、サーバーとファームウェア双方の更新のデプロイが必要です。
帰結
- 正規バイナリエンコーディング(ESP32 → サーバー、ノード → イベントログ)はProtobufを使います。
- HTTP APIは、ブラウザ、CLI、現行ファームウェア互換のためにJSONを維持します。
packages/protocolパッケージがすべての.protoファイルと(将来の)生成コードを所有します。他のパッケージは独自のワイヤフォーマットを定義しません。