JSONでのBase64データ
JSONにバイナリデータを埋め込む際にBase64が使われる理由と方法を解説。エンコード戦略、スキーマの慣習、パフォーマンスへの影響、実際のAPIパターンを紹介します。
詳細な説明
JSONはテキスト文字列、数値、真偽値、null、配列、オブジェクトのみをサポートしています。ネイティブなバイナリデータ型はありません。画像、ファイル、暗号化ペイロードなどのバイナリデータをJSONドキュメントに含める必要がある場合、Base64エンコードが標準的なソリューションです。
基本パターン:
{
"fileName": "report.pdf",
"mimeType": "application/pdf",
"content": "JVBERi0xLjQKJcOkw7zDtsO..."
}
一般的な慣習として、Base64コンテンツと併せてMIMEタイプを含め、消費側がデコード後のバイト列をどう解釈するか分かるようにします。
実際のAPIの例:
Kubernetes Secretsはすべての値をBase64で格納:
{
"apiVersion": "v1",
"kind": "Secret",
"data": {
"username": "YWRtaW4=",
"password": "cDRzc3cwcmQ="
}
}
GitHub APIはファイル内容をBase64で返却:
{
"name": "README.md",
"encoding": "base64",
"content": "IyBNeSBQcm9qZWN0Cg..."
}
スキーマの慣習: JSON SchemaおよびOpenAPI/Swaggerでは、バイナリデータは format: "byte"(Base64エンコード)または format: "binary"(生のバイナリ、主にファイルアップロード用)で定義されます:
{
"type": "string",
"format": "byte",
"description": "Base64-encoded file content"
}
パフォーマンスに関する考慮事項:
- Base64は約33%のサイズオーバーヘッドを追加します。1MBのファイルは約1.37MBのJSON文字列データになります。
- JSONパーサーはBase64文字列全体のメモリを確保する必要があります。大きなペイロードではメモリ圧迫の原因になる可能性があります。数メガバイトを超えるファイルにはストリーミングJSONパーサーやマルチパートアップロードを検討してください。
- JSON内のBase64文字列は特定の文字のエスケープが必要です。実際には、標準Base64の出力にはJSONエスケープが必要な文字(
"や\)が含まれないため、追加のオーバーヘッドは発生しません。
JSONでのBase64の代替手段:
- ファイルアップロードにはマルチパートフォームデータ(33%のオーバーヘッドを回避)
- バイナリデータ用の個別エンドポイント(JSONにはURLの参照のみを含める)
- JSONの代わりにMessagePackやCBOR(ネイティブなバイナリ型をサポート)
よくある間違い: 二重エンコード。データをBase64エンコードしてからJSON.stringifyすれば、Base64文字列は正しく含まれます。しかし、JSONオブジェクト全体を誤ってBase64エンコードしたり、すでにエンコードされた文字列を再度Base64エンコードしたりすると、消費側が複数回デコードしなければならないネストされたエンコードが発生します。
ユースケース
JSONペイロードのみを受け付けるREST APIで、ユーザーがアップロードしたアバター画像をBase64エンコードしてリクエストボディに含めて送信する場合に使用します。