JSONでのBase64データ

JSONにバイナリデータを埋め込む際にBase64が使われる理由と方法を解説。エンコード戦略、スキーマの慣習、パフォーマンスへの影響、実際のAPIパターンを紹介します。

Format

詳細な説明

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エンコードしてリクエストボディに含めて送信する場合に使用します。

試してみる — Base64 Encoder

フルツールを開く