プログラマのための IT 教科書

通信の形式いろいろ

この部の 9 / 12 章 ・ 全体で 30 / 76 章 ・ 読了目安 35 分

この章を読むとできるようになること
  • HTTP 以外の選択肢を知っている
  • なぜ多くの方式が存在するかを説明できる
  • 新しい連携で必ず確認する項目を持つ

Web サービスを作っていると HTTP ばかり使うので、 通信 = HTTP だと思いがちです。

しかし実務では、こういう場面に出会います。

「取引先とのデータ連携は SOAP です」
「バッチの結果は SFTP でファイルを置いてください」
「通知は SMTP で送っています」
「デバイスとの通信は MQTT です」
「銀行との連携は全銀フォーマットの固定長ファイルです」

知らないと、何を調べればいいかも分かりません。 この章は、その地図です。すべてを覚える必要はなく、 「そういうものがある」と知っていることが目的です。

なぜこんなに種類があるのか

プロトコルは、その時代の制約と要求に合わせて生まれます。

1970-80年代  回線が細く高価 → 少ないデータ量で確実に届けることが最優先
             (メール・FTP・EDI)

1990年代     Web の登場 → 誰でも読める、テキストベースの単純な形式
             (HTTP・HTML)

2000年代     企業システムの連携 → 厳密な型定義と、複雑な業務要件
             (SOAP・WS-*)

2010年代     モバイルと大量アクセス → 軽量・高速・非同期
             (REST/JSON・WebSocket・gRPC・MQTT)

2020年代     マイクロサービスと大規模化 → 効率・型安全・双方向
             (gRPC・GraphQL・HTTP/3)

古いものが「悪い」わけではありません。 その時代の要求に対する最適解であり、今も動き続けています。 そして、動いているものは簡単には置き換えられません(既存コードを読む)。

Web で使うもの

プロトコル何のため特徴
HTTP/1.1Web の基本テキスト。1接続1リクエスト(Web と HTTP)
HTTP/2高速化バイナリ・多重化。1接続で並列(DNS・TCP・TLS)
HTTP/3さらに高速化UDP(QUIC)ベース。接続確立が速い
WebSocket双方向・リアルタイム接続を維持し、サーバーからも送れる
Server-Sent Eventsサーバー → クライアントの一方向HTTP のまま。実装が簡単
WebRTCブラウザ間の直接通信音声・映像・P2P

WebSocket と SSE の使い分け

チャット、共同編集、ゲーム   → WebSocket(双方向)
通知、進捗表示、株価の配信   → SSE(サーバーから送るだけ)

SSE は HTTP のままなので、既存のインフラ(CDN・LB・認証)がそのまま使えます。 双方向が要らないなら、こちらのほうが楽です。

WebSocket は「ずっと繋ぎっぱなし」
□ ロードバランサやプロキシがタイムアウトで切ることがある
□ 切れた時の再接続を、自分で実装する必要がある
□ サーバーの接続数が上限になる(プロセスとメモリのファイルディスクリプタ)
□ スケールアウトすると、どのサーバーに繋がっているか管理が要る

「リアルタイムだから WebSocket」と安易に選ばないでください。 数秒の遅れが許されるなら、ポーリングや SSE のほうが単純です。

API の作り方(HTTP の上の流儀)

方式特徴向いている場面
RESTHTTP のメソッドと URL で表現。最も普及一般的な Web API
GraphQLクライアントが欲しい項目を指定する画面ごとに必要な項目が違う、モバイル
gRPCprotobuf + HTTP/2。バイナリ・型安全サービス間通信(スキーマと RPC)
SOAPXML ベース。厳密な仕様企業間連携・金融・行政(今も現役)

SOAP — なぜ生まれ、なぜ減ったか

SOAP の背景

2000年前後、企業システム同士をつなぐ需要が高まりました。 そこで求められたのは、

□ 型が厳密に定義されていること(間違ったデータを送れない)
□ トランザクション・セキュリティ・信頼性の仕様が標準化されていること
□ 言語やベンダーに依存しないこと

SOAP はこれに応えた仕様です。 WSDL という定義ファイルからクライアントコードを自動生成でき、 WS-Security、WS-Transaction といった拡張仕様も整備されました。

では、なぜ減ったのか。

□ XML が冗長で、パースも重い(モバイルには厳しい)
□ 仕様が巨大で、実装ごとの解釈の違いに悩まされた
□ Web の世界では、もっと単純な REST + JSON で十分だった

つまり、「単純さ」が「厳密さ」に勝ったのが2010年代です。

ただし、厳密さが必要な領域では今も使われています。 金融、行政、大企業間の連携で出会う可能性は十分にあります。

<!-- SOAP のリクエストの雰囲気(実際はもっと長い) -->
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Body>
    <GetBalance xmlns="http://example.com/bank">
      <AccountId>12345</AccountId>
    </GetBalance>
  </soap:Body>
</soap:Envelope>
□ WSDL(定義ファイル)が渡されたら、そこからクライアントを生成する
□ 手で XML を組み立てない
□ 文字コードと日時形式の指定に特に注意する(文字コードと改行コード)

この構造は、実は gRPC と同じ発想です(定義ファイルからコード生成)。 違いは、XML かバイナリか、という点にあります。

メッセージング

プロトコル用途
AMQPRabbitMQ などが使う(RabbitMQ と Kafka)
MQTTIoT 向け。極めて軽量。不安定な回線を前提
Kafka の独自プロトコル大量ストリーム(RabbitMQ と Kafka)
STOMPテキストベースで単純
MQTT が軽い理由

IoT デバイスは、電池で動き、回線が細く、頻繁に切れます。

□ ヘッダが極小(最小2バイト)
□ 接続が切れた時の遺言メッセージ(Last Will)を設定できる
□ QoS のレベルを選べる(届かなくてよい / 最低1回 / ちょうど1回)

制約が厳しい環境から要求が生まれ、専用のプロトコルになった例です。

メール

プロトコル役割
SMTP送信。サーバー間の配送もこれ
IMAP受信。サーバー上のメールを操作する(複数端末で同期)
POP3受信。ダウンロードして削除する(古い方式)

「メールを送る」は、実務でも頻繁に実装します。

□ 自前で SMTP サーバーを立てない(到達率が絶望的に低い)
□ 送信サービス(SendGrid / SES / Postmark など)を使う
□ SPF / DKIM / DMARC を設定する ← これが無いと迷惑メール扱いされる
□ バウンス(宛先不明)を処理する
□ 配信停止の導線を必ず入れる(エンジニアと法律の特定電子メール法)
メールは「届いたか分からない」
□ 送信に成功した ≠ 相手に届いた
□ 届いた ≠ 迷惑メールフォルダに入っていない
□ 迷惑メール判定は、送信元の評判で決まる

重要な通知をメールだけに依存しないでください。 アプリ内にも必ず記録を残します(モバイルアプリの実務のプッシュ通知と同じ考え方)。

ファイル転送

古いと思われがちですが、企業間連携では今も主流です。

プロトコル特徴
SFTPSSH 上のファイル転送。現在の標準
SCPSSH 上のコピー。単純
FTPSFTP + TLS
FTP暗号化されない。新規では使わない
rsync差分転送。バックアップや同期に強い
□ 平文の FTP は、認証情報がネットワーク上を流れる → 使わない
□ 鍵認証を使う(パスワードよりも)
□ 転送完了の判定に注意(書き込み途中のファイルを読まないよう、
  一時名で置いてからリネームする)
「置きっぱなし」で連携するシステム
1. こちらが夜間バッチで CSV を SFTP に置く
2. 相手が朝のバッチで取りに来る

今も非常に多い形式です。そして、次の事故が起きます。

□ 書き込み途中のファイルを相手が読んでしまう
   → 一時ファイル名で書き、完了後にリネームする(リネームは原子的)
□ 前日のファイルが残っていて、二重に処理される
□ 文字コードと改行コードの不一致(文字コードと改行コード)
□ 相手が取りに来たかどうかが分からない

バッチとジョブのバッチの原則が、そのまま必要になります。

インフラ・運用で出会うもの

プロトコル用途
SSHサーバーへの安全な接続(マシンとシェル)
DNS名前解決(DNS・TCP・TLS)。UDP が基本
NTP時刻同期。ずれると証明書検証やログの突合が壊れる(見つけにくいバグ)
LDAPディレクトリサービス。社内の認証基盤で使われる
SNMPネットワーク機器の監視
Syslogログの転送
RDP / VNC画面転送

レガシー連携(日本の実務で出会うもの)

教科書には載りませんが、実際には非常に多い領域です。

形式どこで使うか
固定長ファイル銀行(全銀フォーマット)、行政、大企業の基幹システム
EDI企業間の受発注
CSV/TSV + バッチ転送あらゆるところ
専用線・VPN 経由の独自プロトコル金融、公共
□ 桁数が1バイトでもずれると、以降が全部ずれる
□ 半角カナ・Shift_JIS が現役(文字コードと改行コード)
□ 日付が「YYMMDD」で、世紀の判定ルールが独自
□ 数値が右詰めゼロ埋め、負数の表現が独特
□ 仕様書が PDF で、質問すると数日かかる
レガシー連携を軽視しない

「古い」「非効率だ」と思うかもしれませんが、

□ 相手のシステムは変えられない(相手にとっては巨大な資産)
□ 何十年も安定して動いてきた実績がある
□ 変更には、業界全体の調整が必要なことがある

新人が「REST にしましょう」と言って通る話ではありません。

実務でやるべきは、その形式を正確に実装し、 自社の内部では扱いやすい形に変換することです。 ドメイン駆動設計の実践の腐敗防止層(ACL) が、まさにこの場面で効きます。

選び方

□ ブラウザから呼ぶ                    → HTTP(REST / GraphQL)
□ サービス間で高速・型安全に          → gRPC(スキーマと RPC)
□ 画面ごとに必要な項目が違う          → GraphQL
□ サーバーから push したい            → SSE(一方向)/ WebSocket(双方向)
□ 非同期に流したい                    → メッセージング(非同期処理とメッセージング・RabbitMQ と Kafka)
□ 大量のファイル / 定時のやり取り     → SFTP + バッチ(バッチとジョブ)
□ IoT デバイス                        → MQTT
□ 相手が指定してくる                  → **相手に合わせる**(選択の余地は無い)

最後が実務では最も多いことも覚えておいてください。

どの形式でも共通して確認すること

新しい連携を実装する時、必ず確認するリストです。

□ 文字コードと改行コード(文字コードと改行コード)
□ 日時の形式とタイムゾーン(見つけにくいバグ)
□ 数値の形式(桁数、小数、負数、通貨単位)
□ 認証方式(証明書 / 鍵 / ID・パスワード / IP 制限)
□ タイムアウトとリトライの規定(性能と負荷対策)
□ **再送された場合の扱い**(冪等性。非同期処理とメッセージング・間違えられない処理を作る)
□ エラー時の連絡方法と、相手の窓口
□ テスト環境の有無

この8項目は、どのプロトコルでも聞くべきことです。 そして、仕様書に書かれていないことが必ずあります。先に聞いてください。

取引先から「日次の売上データを SFTP で連携してほしい」と言われました。実装で最も注意すべきことは?

まとめ

  • 通信 = HTTP ではない。プロトコルはその時代の制約から生まれる
  • Web では HTTP / WebSocket / SSE。双方向が要らないなら SSE のほうが楽
  • API の流儀は REST / GraphQL / gRPC / SOAP。 SOAP は「厳密さ」の要求から生まれ、今も金融・行政で現役
  • メッセージングは AMQP / MQTT / Kafka。MQTT は IoT の制約から生まれた
  • メールは SMTP / IMAP。自前で立てず、SPF/DKIM/DMARC を設定する。 「届いたか分からない」前提で設計する
  • ファイル転送は SFTP。書き込み途中を読まれない工夫が必須
  • レガシー連携(固定長・EDI)は今も多い。腐敗防止層で内部と分離する
  • 実務では相手が形式を指定してくることが最も多い
  • どの形式でも、文字コード・日時・数値・認証・タイムアウト・冪等性を必ず確認する

公式ドキュメント・参考資料

仕様の最終的な正本は RFC です。読みにくいですが、 「この挙動は仕様上どうなっているのか」を確定させたい時は、ここに戻ります。

次の章では、これらが実際に流れる Web と HTTP を詳しく見ます。

読み終わったら記録しておくと、目次で進み具合が分かります。