外部インターフェース定義書とは
外部インターフェース定義書(External Interface Specification)は、開発するシステムと外部システム(他社サービス・社内他システム・ハードウェア)とのデータ連携仕様を定義した設計書です。API連携・ファイル連携・メッセージキュー連携など、連携方式ごとに作成します。
💡 インターフェース定義書が必要な連携パターン
① 外部APIの呼び出し(決済API・地図API・SMS送信API) ② 他社システムへのリアルタイムAPI連携(ERP・会計システム) ③ ファイル連携(SFTP・S3経由でのCSV/XML交換) ④ メッセージキュー連携(Kafka/RabbitMQ) ⑤ ハードウェア連携(プリンター・スキャナー・POS端末)
① インターフェース一覧の整理
システムが持つ全外部インターフェースをIDを付けて一覧化します。「IN(受信)」と「OUT(送信)」の方向を明示します。
| IF ID | IF名称 | 方向 | 連携先システム | 連携方式 | タイミング | 優先度 |
|---|---|---|---|---|---|---|
| IF-001 | 決済API連携 | OUT | XXX決済サービス | REST API(HTTPS) | 受注確定時(リアルタイム) | Must |
| IF-002 | 決済結果通知受信 | IN | XXX決済サービス | Webhook(HTTP POST) | 決済完了/失敗時(非同期) | Must |
| IF-003 | メール送信 | OUT | SendGrid(外部SMTP) | SendGrid API | 各種メール送信時(リアルタイム) | Must |
| IF-004 | 在庫データ連携(OUT) | OUT | 倉庫管理システム(WMS) | ファイル連携(SFTP/CSV) | 毎日22:00 バッチ | Must |
| IF-005 | 在庫更新データ受信(IN) | IN | 倉庫管理システム(WMS) | ファイル連携(SFTP/CSV) | 毎日08:00 バッチ | Must |
| IF-006 | 売上データ連携 | OUT | 会計システム(freee) | REST API(OAuth2) | 月次締め処理時 | Should |
| IF-007 | 住所検索 | OUT | 郵便番号API(zipcloud) | REST API(HTTP GET) | 住所入力時(リアルタイム) | Should |
② 通信方式・プロトコルの定義
各インターフェースの通信仕様を定義します。
| IF ID | プロトコル | 認証方式 | 接続先URL/ホスト | タイムアウト | リトライ |
|---|---|---|---|---|---|
| IF-001 | HTTPS(TLS 1.2以上) | APIキー(リクエストヘッダー) | https://api.xxx-payment.com/v1/ | 30秒 | 3回(exponential backoff) |
| IF-002 | HTTPS(Webhook受信) | HMACシグネチャ検証 | /webhook/payment/(自システム) | — | —(べき等性保証) |
| IF-004 | SFTP(SSH over TCP/22) | 公開鍵認証 | sftp.warehouse-system.co.jp | 60秒 | 3回(5分間隔) |
③ データフォーマットの定義
各インターフェースで送受信するデータのフォーマット(項目名・型・必須/任意・値の形式)を詳細に定義します。
決済API連携(IF-001)のリクエスト仕様の例:
// POST https://api.xxx-payment.com/v1/charges
// Content-Type: application/json
// Authorization: Bearer {API_KEY}
{
"order_id": "OD-000001", // 必須 / string / 自システム受注番号(最大50文字)
"amount": 15000, // 必須 / integer / 金額(円)/ 1以上10,000,000未満
"currency": "JPY", // 必須 / string / 通貨コード(現在JPYのみ)
"customer_id": "CUST-001", // 必須 / string / 顧客識別子
"card_token": "tok_xxxxxxxxxx", // 必須 / string / カードトークン(フロントエンドで取得)
"description": "受注番号OD-000001の決済", // 任意 / string / 最大200文字
"metadata": { // 任意 / object / 追加情報(ログ用)
"product_count": 3,
"customer_email": "customer@example.com"
}
}
// レスポンス(成功 HTTP 200)
{
"charge_id": "chr_xxxxxxxxxx", // 決済ID(自システムで保存必須)
"status": "succeeded", // "succeeded" / "pending" / "failed"
"amount": 15000,
"created_at": "2026-06-17T10:00:00Z"
}
④ エラーハンドリング・リトライ設計
外部インターフェースは通信エラー・タイムアウト・相手システムエラーが発生しうるため、エラー発生時の動作を設計段階で定義します。
| エラー種別 | 発生条件 | システムの動作 | ユーザーへの通知 |
|---|---|---|---|
| タイムアウト | APIレスポンスが30秒以内に返らない | 3回リトライ後、受注を「決済待ち」状態で保留。アラートメール送信 | 「ただいまシステムが混み合っています。しばらくお待ちください」 |
| カードエラー(4xx) | カード残高不足・有効期限切れ等 | リトライなし。決済失敗として受注ステータスを更新 | 「決済が承認されませんでした。別のカードをお試しください」 |
| サーバーエラー(5xx) | 決済サービス側のシステムエラー | 3回リトライ(exponential backoff)後にアラート送信。手動対応待ちで保留 | 「決済サービスが一時的に利用できません。後ほど再度お試しください」 |
| Webhook未受信 | Webhook通知が1時間以内に到達しない | バッチで決済IDの状態を問い合わせ(Polling)して更新 | —(バックグラウンド処理) |
⑤ ファイル連携の定義
SFTP経由のファイル連携は、ファイル名・文字コード・区切り文字・配置パス・ファイルの取り込み完了通知方法を定義します。
| 定義項目 | 送信(IF-004) | 受信(IF-005) |
|---|---|---|
| ファイル形式 | CSV | CSV |
| 文字コード | UTF-8(BOMなし) | UTF-8(BOMなし) |
| 区切り文字 | カンマ(,) | カンマ(,) |
| 改行コード | LF(Unix形式) | LF(Unix形式) |
| ファイル名形式 | stock_order_YYYYMMDD.csv | stock_update_YYYYMMDD.csv |
| 配置パス(SFTP) | /out/stock/ | /in/stock/ |
| 完了通知方法 | 同名 .done ファイルを配置(例:stock_order_20260617.done) | 受信側が .done ファイルを確認してから取り込み開始 |
| ヘッダー行 | 1行目にカラム名を記載 | 1行目にカラム名を記載 |
Python Tips — 連携ファイルをバリデーション・変換する
"""
SFTPから連携ファイル(CSV)を受信してバリデーション・DB投入するスクリプト。
pip install paramiko pandas psycopg2-binary
"""
import paramiko
import pandas as pd
import psycopg2
from datetime import date
from pathlib import Path
import logging
logging.basicConfig(level=logging.INFO, format="%(asctime)s [%(levelname)s] %(message)s")
log = logging.getLogger(__name__)
SFTP_CONFIG = {
"hostname": "sftp.warehouse-system.co.jp",
"port": 22,
"username": "appuser",
"key_filename": "/etc/keys/wms_rsa", # 秘密鍵パス
}
REMOTE_DIR = "/in/stock/"
LOCAL_DIR = Path("/tmp/wms_files/")
LOCAL_DIR.mkdir(exist_ok=True)
# 受信ファイルの必須カラム
REQUIRED_COLS = ["product_code", "warehouse_code", "stock_quantity", "updated_at"]
def download_today_file() -> Path | None:
"""本日付の在庫更新ファイルをSFTPからダウンロードする"""
today = date.today().strftime("%Y%m%d")
remote_csv = f"{REMOTE_DIR}stock_update_{today}.csv"
remote_done = f"{REMOTE_DIR}stock_update_{today}.done"
local_csv = LOCAL_DIR / f"stock_update_{today}.csv"
with paramiko.SSHClient() as ssh:
ssh.set_missing_host_key_policy(paramiko.RejectPolicy())
ssh.connect(**SFTP_CONFIG)
with ssh.open_sftp() as sftp:
# .doneファイルの存在確認(取り込み完了通知)
try:
sftp.stat(remote_done)
except FileNotFoundError:
log.warning(f".doneファイルがありません: {remote_done}")
return None
# CSVファイルをダウンロード
sftp.get(remote_csv, str(local_csv))
log.info(f"ダウンロード完了: {remote_csv} → {local_csv}")
return local_csv
def validate_stock_csv(df: pd.DataFrame) -> list[str]:
"""在庫更新CSVのバリデーション"""
errors = []
for col in REQUIRED_COLS:
if col not in df.columns:
errors.append(f"必須カラム '{col}' がありません")
if errors:
return errors
# 件数チェック
if len(df) == 0:
errors.append("データが0件です")
# 数値チェック
try:
df["stock_quantity"] = pd.to_numeric(df["stock_quantity"])
if (df["stock_quantity"] < 0).any():
errors.append("在庫数量に負の値があります")
except Exception:
errors.append("stock_quantity に数値以外の値があります")
# 重複チェック(商品コード × 倉庫コードの組み合わせ)
dup = df.duplicated(subset=["product_code", "warehouse_code"])
if dup.any():
errors.append(f"重複レコードあり: {df[dup][['product_code','warehouse_code']].to_dict('records')}")
return errors
if __name__ == "__main__":
csv_path = download_today_file()
if csv_path is None:
log.info("本日の連携ファイルはまだ準備されていません")
exit(0)
df = pd.read_csv(csv_path, encoding="utf-8", dtype={"product_code": str})
log.info(f"読込件数: {len(df)}件")
errors = validate_stock_csv(df)
if errors:
log.error("バリデーションエラー:")
for e in errors:
log.error(f" {e}")
exit(1)
log.info("バリデーションOK — DB投入処理を開始します")
# DB投入処理は省略(post-03-data-items.htmlのサンプルを参照)
定義チェックリスト
| チェック項目 | 確認ポイント |
|---|---|
| □ 全外部インターフェースが一覧化されているか | IN/OUTの方向・連携先・方式・タイミングが全IFに定義されているか |
| □ 通信仕様が定義されているか | プロトコル・認証方式・接続先URL・タイムアウト値が定義されているか |
| □ データフォーマットが項目レベルで定義されているか | 全送受信項目の名称・型・必須/任意・値の形式が定義されているか |
| □ エラーハンドリングが定義されているか | タイムアウト・サーバーエラー・ビジネスエラー各ケースの動作が定義されているか |
| □ ファイル連携の仕様が定義されているか | 文字コード・改行コード・ファイル名・配置パス・完了通知方法が定義されているか |
| □ 外部サービス側の仕様書を確認しているか | 連携先の最新APIドキュメントを確認済みか。バージョン情報が記録されているか |