# Baggage API

> Source: https://www.ymotongpoo.com/works/otel-specs-ja/spec/baggage/api/


**ステータス**: [Stable](../../document-status/)

## Overview

`Baggage`は、分散リクエストやワークフローの実行に文脈的に関連付けられたアプリケーション定義のプロパティの集合です（[W3C Baggage Specification][w3c]も参照してください）。バゲージは、他の用途に加えて、テレメトリーへの注釈付けや、メトリクス・トレース・ログへの文脈情報の付加に使えます。

OpenTelemetryにおいて`Baggage`は、ユーザー定義のプロパティを記述する名前・値の組の集合として表現されます。`Baggage`内の各名前は、_厳密に1つの値_にMUST関連付けられるものとします。これは、同じ名前に対する重複するエントリーを許容する[W3C Baggage Specification, § 3.2.1.1](https://www.w3.org/TR/baggage/#baggage-string)よりも制限が強くなっています。

バゲージの**名前**は、任意の有効な空でないUTF-8文字列です。言語APIは、バゲージの**名前**として使える文字列をSHOULD NOT制限するものとします。しかし、バゲージのエントリーをコンポーネントの境界を越えて送信するために使われる特定の`Propagator`は、バゲージの名前に独自の制約を課すことがあります。例えば[W3C Baggageの仕様](https://www.w3.org/TR/baggage/#key)は、バゲージのキーを[RFC7230, Section 3.2.6](https://datatracker.ietf.org/doc/html/rfc7230#section-3.2.6)の`token`の定義を満たす文字列に制限しています。最大限の互換性のため、バゲージの名前には英数字を使うことが強く推奨されます。

バゲージの**値**は、任意の有効なUTF-8文字列です。言語APIは、`Set`においてバゲージの**値**として任意の有効なUTF-8文字列をMUST受け付けるものとし、`Get`から同じ値をMUST返すものとします。

言語APIは、バゲージの名前と値の両方を大文字・小文字を区別するものとしてMUST扱うものとします。[W3C Baggage Rationale](https://github.com/w3c/baggage/blob/main/baggage/HTTP_HEADER_FORMAT_RATIONALE.md#case-sensitivity-of-keys)も参照してください。

例:

```
baggage.Set('a', 'B% 💼');
baggage.Set('A', 'c');
baggage.Get('a'); // "B% 💼" を返す
baggage.Get('A'); // "c" を返す
```

Baggage APIは以下から構成されます。

- 論理的なコンテナとしての`Baggage`
- `Context`内の`Baggage`と相互作用する関数群

ここで説明する関数は、`Baggage`の内容全体を表す構造体・オブジェクトを持つことによって`Baggage`と相互作用するための1つのアプローチです。言語の慣用表現によっては、言語APIは`Context`を直接介してバゲージと相互作用することでこれらの関数をMAY実装してもよいものとします。

Baggage APIは、SDKがインストールされていない状態でも完全に機能しなければなりません（MUST）。これは、透過的なプロセス間のバゲージ伝搬を可能にするために必要です。Baggage propagatorがAPIにインストールされている場合、SDKがインストールされているかどうかに関わらず動作します。

`Baggage`コンテナは不変でなければならず（MUST）、それを含む`Context`もまた不変であり続けます。

## Operations

### Get Value

以前のイベントによって設定された名前・値の組の値にアクセスするために、Baggage APIは、名前を入力として受け取り、指定された名前に関連付けられた値を返す関数、あるいは指定された名前が存在しない場合はnullを返す関数をMUST提供するものとします。

REQUIREDパラメータ:

`Name` 値を返す対象の名前。

### Get All Values

`Baggage`内の名前・値の組を返します。名前・値の組の順序はMUST NOT重要であるものとします。言語の特性に応じて、返される値は不変のコレクションでも、`Baggage`内の名前・値の組の不変のコレクションに対するイテレーターでも構いません。

### Set Value

名前・値の組の値を記録するために、Baggage APIは、名前と値を入力として受け取る関数をMUST提供するものとします。新しい値を含む新しい`Baggage`を返します。言語の慣用表現によっては、言語APIは`Builder`パターンを使い、`Baggage`から`Builder`を構築する方法を公開することでこれらの関数をMAY実装してもよいものとします。

REQUIREDパラメータ:

`Name` 値を設定する対象の名前。文字列型。

`Value` 設定する値。文字列型。

OPTIONALパラメータ:

`Metadata` 名前・値の組に関連付けられる任意のメタデータ。これは意味を持たない文字列の不透明なラッパーであるべきです。将来の機能のために不透明なままにされています。

### Remove Value

名前・値の組を削除するために、Baggage APIは、名前を入力として受け取る関数をMUST提供するものとします。選択された名前を含まない新しい`Baggage`を返します。言語の慣用表現によっては、言語APIは`Builder`パターンを使い、`Baggage`から`Builder`を構築する方法を公開することでこれらの関数をMAY実装してもよいものとします。

REQUIREDパラメータ:

`Name` 削除する対象の名前。

## Context Interaction

本節は、[`Context`](../../context/)と相互作用するBaggage API内のすべての操作を定義します。

このAPIの実装が`Context`を直接操作しない場合、`Context`インスタンスと相互作用するために以下の機能をMUST提供するものとします。

- `Context`インスタンスから`Baggage`を抽出する
- `Context`インスタンスに`Baggage`を挿入する

上記の機能が必要なのは、APIのユーザーがBaggage APIの実装が使う[Context Key](../../context/#create-a-key)へのアクセスをSHOULD NOT持つべきであるためです。

言語が暗黙的に伝搬される`Context`をサポートしている場合（[こちら](../../context/#optional-global-operations)を参照）、APIは以下の機能もSHOULD提供するものとします。

- 暗黙のコンテキストから現在アクティブな`Baggage`を取得する。これは、暗黙のコンテキストを取得し、そのコンテキストから`Baggage`を抽出することと同等です。
- 現在アクティブな`Baggage`を暗黙のコンテキストに設定する。これは、暗黙のコンテキストを取得し、そのコンテキストに`Baggage`を挿入することと同等です。

上記のすべての機能は、コンテキストAPIのみを操作するものであり、baggageモジュールの静的メソッド、baggageモジュール内のクラス（`BaggageUtilities`という名前でMAY構いません）の静的メソッド、または`Baggage`クラスのメソッドとしてMAY公開されても構いません。この機能は、可能な場合はAPI内で完全に実装されるべきです（SHOULD）。

### Clear Baggage in the Context

信頼されていないプロセスにいかなるバゲージの名前・値の組も送信しないようにするため、Baggage APIは、コンテキストからすべてのバゲージのエントリーを削除する方法をMUST提供するものとします。

この機能は、ユーザーが空の`Baggage`オブジェクト・構造体をコンテキストに設定できるようにすることで実装しても、`Context`を入力として受け取り、`Baggage`が関連付けられていない新しい`Context`を返すAPIを提供することで実装しても構いません。

## Propagation

`Baggage`は、プロセス境界を越えて、あるいは任意の境界（プロセス、$OTHER_BOUNDARY1、$OTHER_BOUNDARY2など）を越えて、様々な理由でMAY伝搬されても構いません。

APIレイヤーまたは拡張パッケージは、以下の`Propagator`をMUST含むものとします。

* [W3C Baggage Specification][w3c]を実装する`TextMapPropagator`。

propagatorがどのように配布されるかについては[Propagators Distribution](../../context/api-propagators/#propagators-distribution)を参照してください。

環境変数をプロセス間のキャリア機構として使う場合の伝搬の扱いについては[Environment Variable Carriers](../../context/env-carriers/)を参照してください。

注: W3C baggageの仕様は現時点で、任意のメタデータに意味を割り当てていません。

`extract`時、propagatorはすべてのメタデータをエントリーごとに単一のメタデータインスタンスとして保存すべきです（should）。`inject`時、propagatorはW3Cの仕様の形式に従ってメタデータを追記すべきです（should）。これらの操作が従うべき追加の要件については、API Propagatorsの[Operation](../../context/api-propagators/#operations)節を参照してください。

## Conflict Resolution

新しい名前・値の組が追加され、その名前が既存の名前と同じ場合、新しい組はMUST優先されるものとします。値は（ローカルで生成されたものかリモートのピアから受信したものかに関わらず）追加された値で置き換えられます。

[w3c]: https://www.w3.org/TR/baggage/

