出荷APIテスト
このガイドでは、一般的なAPIテストの原則に基づき、Equinix Shipments APIの具体的なテストアプローチと例を示します。
Shipments API の概要
Shipments APIを利用すると、エクイニクスIBXデータセンターへのインバウンドおよびアウトバウンドの出荷をプログラムでスケジュール・管理できます:
- インバウンド出荷のスケジューリング(荷物の受け取り)
- 出荷のスケジューリング(パッケージの送信)
- 出荷の詳細の更新
- 出荷追跡情報の管理
- 輸送会社の情報と追跡番号の取り扱い
重要なお知らせ: すべてのインバウンドおよびアウトバウンドの発送は、24時間前までにご予約ください。Equinix APIは、実際の出荷リクエストを作成するプロダクションシステムです。意図しない運用作業が発生しないよう、常に以下のテストのベストプラクティスに従ってください。
出荷テストのワークフロー
Shipments API をテストする前に、以下を確認してください:
- 出荷発注権限を持つ有効なAPI認証情報
- お客様がケージをお持ちのエクイニクスIBX拠点へのアクセス
- 出荷先で有効なケージID
- 輸送会社の要件と追跡番号フォーマットの理解
インバウンド出荷リクエストの作成
import requests
import json
from datetime import datetime, timedelta
# Setup authentication
auth_url = "https://api.equinix.com/oauth2/v1/token"
auth_payload = {
"grant_type": "client_credentials",
"client_id": "YOUR_CLIENT_ID",
"client_secret": "YOUR_CLIENT_SECRET"
}
auth_response = requests.post(auth_url, data=auth_payload)
token = auth_response.json()["access_token"]
# Test creating an inbound shipment request
base_url = "https://api.equinix.com/colocations/v2"
headers = {
"Authorization": f"Bearer {token}",
"Content-Type": "application/json"
}
# Calculate delivery date (24+ hours in advance as required)
delivery_date = (datetime.utcnow() + timedelta(days=2)).isoformat() + "Z"
# Example: Create an inbound shipment request
inbound_payload = {
"type": "INBOUND",
"requestedDateTime": delivery_date,
"cageId": "SV1:01:001MC3",
"customerReferenceId": "SHIP-REF-12345",
"description": "Server hardware delivery for data center expansion project",
"details": {
"carrier": "DHL",
"carrierTrackingNumbers": [
"1234567890123",
"1234567890124"
],
"numberOfBoxes": 2,
"accountNumber": "12345"
},
"purchaseOrder": {
"type": "EXISTING",
"number": "PO-789456"
},
"attachments": [
{
"id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"name": "packing_list.pdf"
}
],
"contacts": [
{
"type": "TECHNICAL",
"registeredUsers": ["tech.admin@example.com"],
"availability": "WORK_HOURS",
"timezone": "America/New_York"
},
{
"type": "NOTIFICATION",
"registeredUsers": ["notifications@example.com"]
}
]
}
create_response = requests.post(
f"{base_url}/orders/shipments",
headers=headers,
data=json.dumps(inbound_payload)
)
# Verify response
assert create_response.status_code == 201, f"Failed to create shipment: {create_response.text}"
# Extract order ID from Location header
order_number = create_response.json()["OrderNumber"]
print(f"Successfully created inbound shipment with order ID: {order_number}")
出荷依頼の作成
# Example: Create an outbound shipment request
outbound_payload = {
"type": "OUTBOUND",
"requestedDateTime": delivery_date,
"cageId": "SV1:01:001MC3",
"customerReferenceId": "OUT-SHIP-67890",
"description": "Returning defective network equipment to vendor",
"details": {
"carrier": "FEDEX",
"carrierTrackingNumbers": [
"987654321098"
],
"numberOfBoxes": 1,
"pickupLocation": "Main cage entrance",
"specialInstructions": "Handle with care - contains sensitive electronic equipment"
},
"purchaseOrder": {
"type": "EXEMPTED"
},
"contacts": [
{
"type": "TECHNICAL",
"registeredUsers": ["shipping@example.com"],
"availability": "ANYTIME"
}
]
}
outbound_response = requests.post(
f"{base_url}/orders/shipments",
headers=headers,
data=json.dumps(outbound_payload)
)
assert outbound_response.status_code == 201, f"Failed to create outbound shipment: {outbound_response.text}"
order_number = outbound_response.json()["OrderNumber"]
print("Successfully created outbound shipment request with order ID: {order_number}")
エラーシナリオのテスト
API実装のエラー処理は必ずテストしてください:
# Test with invalid carrier
invalid_carrier_payload = {
"type": "INBOUND",
"requestedDateTime": delivery_date,
"cageId": "SV1:01:001MC3",
"details": {
"carrier": "INVALID_CARRIER", # Invalid carrier
"carrierTrackingNumbers": ["1234567890"],
"numberOfBoxes": 1
},
"contacts": [
{
"type": "TECHNICAL",
"registeredUsers": ["test@example.com"]
}
]
}
error_response = requests.post(
f"{base_url}/orders/shipments",
headers=headers,
data=json.dumps(invalid_carrier_payload)
)
# Verify error response
assert error_response.status_code == 400, f"Expected error but got: {error_response.status_code}"
error_data = error_response.json()
assert any("carrier" in error["errorMessage"].lower() for error in error_data), "Expected carrier validation error"
# Test with insufficient advance notice (less than 24 hours)
insufficient_time_payload = {
"type": "INBOUND",
"requestedDateTime": (datetime.utcnow() + timedelta(hours=12)).isoformat() + "Z", # Only 12 hours advance
"cageId": "SV1:01:001MC3",
"details": {
"carrier": "DHL",
"carrierTrackingNumbers": ["1234567890"],
"numberOfBoxes": 1
},
"contacts": [
{
"type": "TECHNICAL",
"registeredUsers": ["test@example.com"]
}
]
}
time_error_response = requests.post(
f"{base_url}/orders/shipments",
headers=headers,
data=json.dumps(insufficient_time_payload)
)
assert time_error_response.status_code == 400, f"Expected time validation error but got: {time_error_response.status_code}"
出荷APIテストのベストプラクティス
- 24時間前ルール :必ず24時間以上前に出荷の予定を立ててください。
- 有効な追跡番号 :各キャリアごとに現実的な追跡番号形式を使用してください。
- 適切な連絡先情報 :納品窓口に連絡できるようにしてください。
- ケージアクセス :テスト前のケージIDとアクセス許可の確認
- 国際配送 :国際配送のための税関要件を考慮
- 特別指示 :様々な特別な取り扱いが要求されるテスト
- ファイル添付 :パッキングリストと特別指示書のテスト添付ファイルのアップロード
- タイムゾーン :スケジューリングのためのタイムゾーン変換を適切に処理
- 発注書 :異なるPOタイプ(NEW、EXISTING、EXEMPTED)のテスト
自動化に関する考察
Shipments API を中心に自動化を構築する場合:
- 24時間前スケジューリング要件の検証を実装
- 追跡番号フォーマットのキャリア固有の検証をビルドイン
- キャリアの可用性と容量の問題に対する適切なエラー処理を含みます。
- 出荷状況更新のためのWebhookレシーバーの実装
- すべての出荷トランザクションの監査ロギングの構築
- リクエストを作成する前に、ケージへのアクセスと権限を検証します。
- 海外拠点のタイムゾーンを適切に処理