外部インターフェース定義書とは

外部インターフェース定義書(External Interface Specification)は、開発するシステムと外部システム(他社サービス・社内他システム・ハードウェア)とのデータ連携仕様を定義した設計書です。API連携・ファイル連携・メッセージキュー連携など、連携方式ごとに作成します。

💡 インターフェース定義書が必要な連携パターン

① 外部APIの呼び出し(決済API・地図API・SMS送信API) ② 他社システムへのリアルタイムAPI連携(ERP・会計システム) ③ ファイル連携(SFTP・S3経由でのCSV/XML交換) ④ メッセージキュー連携(Kafka/RabbitMQ) ⑤ ハードウェア連携(プリンター・スキャナー・POS端末)

① インターフェース一覧の整理

システムが持つ全外部インターフェースをIDを付けて一覧化します。「IN(受信)」と「OUT(送信)」の方向を明示します。

IF IDIF名称方向連携先システム連携方式タイミング優先度
IF-001決済API連携OUTXXX決済サービスREST API(HTTPS)受注確定時(リアルタイム)Must
IF-002決済結果通知受信INXXX決済サービスWebhook(HTTP POST)決済完了/失敗時(非同期)Must
IF-003メール送信OUTSendGrid(外部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-001HTTPS(TLS 1.2以上)APIキー(リクエストヘッダー)https://api.xxx-payment.com/v1/30秒3回(exponential backoff)
IF-002HTTPS(Webhook受信)HMACシグネチャ検証/webhook/payment/(自システム)—(べき等性保証)
IF-004SFTP(SSH over TCP/22)公開鍵認証sftp.warehouse-system.co.jp60秒3回(5分間隔)

③ データフォーマットの定義

各インターフェースで送受信するデータのフォーマット(項目名・型・必須/任意・値の形式)を詳細に定義します。

決済API連携(IF-001)のリクエスト仕様の例:

JSON — 決済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)
ファイル形式CSVCSV
文字コードUTF-8(BOMなし)UTF-8(BOMなし)
区切り文字カンマ(,)カンマ(,)
改行コードLF(Unix形式)LF(Unix形式)
ファイル名形式stock_order_YYYYMMDD.csvstock_update_YYYYMMDD.csv
配置パス(SFTP)/out/stock//in/stock/
完了通知方法同名 .done ファイルを配置(例:stock_order_20260617.done受信側が .done ファイルを確認してから取り込み開始
ヘッダー行1行目にカラム名を記載1行目にカラム名を記載

Python Tips — 連携ファイルをバリデーション・変換する

Python — SFTPで連携ファイルを受信・バリデーションする
"""
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ドキュメントを確認済みか。バージョン情報が記録されているか