導入
API開発において、JSON形式のリクエストは一般的ですが、ファイルアップロードを含む「Multipart/form-data」のテストは、多くのエンジニアが躓きやすいポイントです。特に、バイナリデータと通常のテキストフィールドを混在させた際のリクエスト構築や、境界値テストにおけるバリデーションの検証は、システムの堅牢性を左右します。本記事では、手動テストから自動化まで、実務で役立つMultipartリクエストの攻略法を解説します。
基礎知識
Multipart/form-dataとは、HTTPリクエストでファイル送信を行うために策定されたContent-Typeです。通常のJSON(application/json)と異なり、リクエストボディを「境界値(Boundary)」という文字列で区切り、複数のパーツ(ファイルや文字列)に分けて送信します。バックエンド側では、このBoundaryを解釈してバイナリ部分とフィールド部分を分離して処理しています。この仕組みを理解していないと、Content-Typeヘッダーの不整合や、Boundaryの定義漏れによるリクエストエラーに悩まされることになります。
実装/解決策
実務でのテストは、PostmanのようなGUIツールで感覚を掴んだ後、Pythonのrequestsライブラリを用いて自動化するのが定石です。
1. GUIツールでの検証: Postmanの「Body」タブで「form-data」を選択し、Keyの型を「File」に設定して検証を行います。この際、ネットワークタブを確認し、どのようなBoundaryが生成されているかを確認してください。
2. 自動化のステップ: テストコードでは、ファイルを開く際に「rb(バイナリ読み込み)」モードを徹底します。また、Content-Typeヘッダーはライブラリが自動で適切なBoundaryを生成してくれるため、手動で設定しないのがトラブルを避けるコツです。
サンプルプログラム
以下は、Pythonのrequestsライブラリを使用した実用的なファイルアップロードのテストコードです。
import requests
アップロードするファイルのパス
file_path = ‘test_image.png’
送信先のAPIエンドポイント
url = ‘https://api.example.com/v1/upload’
送信したい追加フィールド
payload = {
‘user_id’: ‘12345’,
‘category’: ‘profile_icon’
}
ファイルをバイナリモードで開く
with open(file_path, ‘rb’) as f:
# filesパラメータに辞書形式で渡す
files = {‘file’: (file_path, f, ‘image/png’)}
# データを送信(Content-Typeはrequestsが自動でMultipart/form-dataに設定します)
response = requests.post(url, data=payload, files=files)
結果の検証
if response.status_code == 200:
print(‘アップロード成功:’, response.json())
else:
print(‘エラー発生:’, response.status_code, response.text)
応用・注意点
現場で陥りやすいバグとして、「メモリ不足」と「Content-Typeの二重指定」が挙げられます。
まず、巨大なファイルを扱う場合、メモリに全データを読み込むとサーバーがダウンする可能性があります。ストリーム形式でのアップロードを検討してください。
次に、HTTPリクエストヘッダーに手動で「Content-Type: multipart/form-data」を記述してしまうケースです。これを行うと、ライブラリ側が自動生成する「Boundary(区切り文字)」が含まれず、バックエンドがデータを正しく解析できなくなります。ライブラリの自動生成機能に任せ、ヘッダーのContent-Typeは明示的に指定しないことが、最も安全な実装方法です。

コメント