Azure Data Factory(ADF)で外部のREST APIと連携する際、必ず議論になるのが「REST Linked Service(REST LS)」と「Web Activity」のどちらを使うべきかというテーマです。本記事では両者の思想と役割を整理し、選定基準・設計パターン・パフォーマンス・セキュリティ・運用までを実務目線で徹底解説します。迷わない判断軸とすぐ使えるレシピをまとめました。
Azure Data Factoryにおける「REST LS」と「Web Activity」の核心
まず両者は“どちらが上位互換か”ではなく目的が違うと押さえるのが最重要です。
| 項目 | REST Linked Service(REST LS) | Web Activity |
|---|---|---|
| 役割 | REST APIへの接続定義(ベースURL・認証・共通ヘッダー等)を一元管理。単体では実行されず、Copy ActivityやMapping Data Flowから参照される。 | パイプライン内でHTTPリクエストを実際に送るアクション。GET/POST/PUT/DELETE等で軽量な呼び出しや制御に使う。 |
| 目的 | データの移動・取り込み・変換(高スループット、ページング、並列化)。 | 外部サービスの起動・状態確認・通知・分岐などオーケストレーション。 |
| 主な併用先 | Copy Activity / Lookup / Mapping Data Flow / Synapse(コピー) | If Condition / Until / Set Variable / Switch / ForEach などの制御アクティビティ |
| 強み | 接続定義の再利用、コピーの並列実行、ページングによる大容量取り込み、認証情報の一元管理。 | 設定がシンプル、動的パラメータで即時呼び出し、レスポンスを次アクティビティに受け渡し可能。 |
| 弱み | 単発呼び出しには過剰、オーケストレーション単体の用途には向かない。 | レスポンス本文の取り回しに上限(目安として数MB級の大容量のダウンロードには不向き)、長時間ストリーミングや大量並列は非効率。 |
| 典型データ量 | 数MB〜GB級の連続取り込みに強い。 | 数KB〜数MB未満の軽量応答に適する。 |
| 認証 | サービス プリンシパル、マネージドID(Managed Identity)などを前提とした機械連携に強い。 | ベーシック/ベアラトークン等の簡易実装が容易。複雑なOAuthフローは不得手。 |
| コスト観点 | コピー課金(データ移動)+オーケストレーション課金。大容量のデータ連携でも単価効率が出やすい。 | オーケストレーション課金のみ。制御や通知の小粒な呼び出しでコスパ良。 |
| 保守性 | 接続・認証の集中管理、鍵ローテーションの一括化。 | パイプライン内で完結しやすいが、接続先が増えると重複設定のメンテが課題。 |
選択指針:迷ったらこのチェックリスト
- 継続的にデータを取り込みたいか? → はい:REST LS + Copy Activity/いいえ(制御中心):Web Activity
- 取得データ量は大きいか? → 大きい:REST経由のCopy/Lookup/小さい:Web Activity
- 認証は複雑か? → クライアント資格情報やマネージドID等の機械認証:REST LS/単純トークン・ベーシック:Web Activity可
- ページングや並列で高速化したいか? → はい:REST LS側のCopy設定でスケール/いいえ:Web Activityで十分
- 同じ接続を複数パイプラインで使うか? → はい:REST LSで集約/いいえ:Web Activity単体でも可
代表ユースケースと推奨構成
| シナリオ | 推奨構成 | ポイント |
|---|---|---|
| SaaSから日次で大量JSONを取り込みData Lakeへ | REST LS → Copy Activity | ページング・並列化・増分抽出で高スループット。 |
| Databricksジョブを起動して完了をポーリング | Web Activity(起動)→ Until(状態確認) | 状態コード/本文を分岐に利用。タイムアウト・リトライ設計が鍵。 |
| パイプライン終了時にTeamsへ通知 | Web ActivityでWebhook | ペイロードを動的に組み立て、エラー時のみ送信も容易。 |
| 複数パイプラインで共通のAPIトークンを活用 | REST LSに認証を集約 | 鍵ローテーション・権限境界の統制が容易。 |
設計の全体像:3つのパターン
データ連携重視パターン(推奨:REST LS + Copy)
大量データの取得・蓄積ではCopy Activityが主役です。REST LSで認証とベースURLを定義し、Dataset(RestResource)で相対パスやクエリをパラメータ化。CopyのソースにREST、シンクにADLS Gen2やSQLを指定します。ページング・並列化が効くため、Web Activityに比べて大容量で安定・高速です。
オーケストレーション重視パターン(Web Activity)
外部ジョブの起動、状態確認、通知、軽量なメタデータ取得はWeb Activityが最短ルート。レスポンスを@activity('Web呼び出し').outputで受け取り、If/Until/Switchで次の分岐を制御します。小粒・高頻度の制御処理に最適です。
ハイブリッドパターン(Webで制御 → REST+Copyで取り込み)
たとえば「事前にトークンを発行(Web)→ページング情報を解決(Web)→本体データの取り込み(REST+Copy)」のように、制御とデータ移動を役割分担すると、柔軟性とスループットを両立できます。
実装レシピ:すぐ使える最低構成
REST Linked Service(Managed Identity)の例
{
"name": "ls_rest_example",
"properties": {
"type": "RestService",
"typeProperties": {
"url": "https://api.contoso.com/",
"authenticationType": "ManagedServiceIdentity",
"resource": "https://api.contoso.com"
}
}
}
Dataset(相対URLとメソッドをパラメータ化)
{
"name": "ds_rest_items",
"properties": {
"type": "RestResource",
"linkedServiceName": { "referenceName": "ls_rest_example", "type": "LinkedServiceReference" },
"parameters": {
"path": { "type": "String" },
"method": { "type": "String", "defaultValue": "GET" }
},
"typeProperties": {
"relativeUrl": "@{dataset().path}",
"requestMethod": "@{dataset().method}"
}
}
}
Copy Activity(REST→Data Lake)
{
"name": "CopyRestToLake",
"type": "Copy",
"typeProperties": {
"source": {
"type": "RestSource",
"paginationRules": { "AbsoluteUrl": "$.next" }
},
"sink": {
"type": "DelimitedTextSink"
}
},
"inputs": [{ "referenceName": "ds_rest_items", "type": "DatasetReference",
"parameters": { "path": "v1/items" } }],
"outputs": [{ "referenceName": "ds_lake_raw", "type": "DatasetReference" }]
}
上例ではレスポンス本文の$.nextから次ページURLを抽出する想定です。実APIの仕様に合わせてJSONPath/ヘッダー参照・オフセット/リミット・カーソル方式などを組み合わせます。
Web Activity(ジョブ起動→レスポンスで分岐)
{
"name": "StartJob",
"type": "WebActivity",
"typeProperties": {
"url": "https://api.contoso.com/jobs",
"method": "POST",
"headers": {
"Content-Type": "application/json",
"Authorization": "@{concat('Bearer ', activity('GetToken').output.body.access_token)}"
},
"body": "@{string(pipeline().parameters.payload)}"
},
"policy": {
"timeout": "01:00:00",
"retry": 3,
"retryIntervalInSeconds": 20
}
}
後続のIf Conditionで@equals(activity('StartJob').output.statusCode, 202)のように分岐できます。トークン取得をWeb Activityで呼ぶ場合は、トークンを変数に退避して再利用するのが定石です。
ページングの実践パターン
- AbsoluteUrl方式:本文またはヘッダーから次ページの絶対URLをJSONPathで抽出。
- Offset/Limit方式:
offsetとlimitをクエリで増分。ForEach+Copyで並列化すると高速。 - Continuation Token方式:本文内の
nextToken等を抽出し、次の要求ヘッダー/クエリに差し込み。
ページングはCopy Activityの管轄に寄せると、並列実行・再実行性・監視の点で有利です。Web Activityでループを自作するのは保守と性能の両面で非推奨です。
増分取得の設計(UpdatedSince/水位制御)
APIがupdatedSinceやmodified_afterをサポートしていれば、パイプライン変数・キーバリューストア(Key Vaultやメタデータテーブル)に「前回成功時刻」を保持し、次回はその時刻から取得します。以下は簡易的な式の例です。
@{coalesce(pipeline().parameters.since, formatDateTime(addDays(utcNow(), -1), 'yyyy-MM-ddTHH:mm:ssZ'))}
取得範囲を重ね(オーバーラップ)させ、シンク側でupsertや重複排除を行うと取りこぼしに強くなります。
セキュリティとガバナンスの勘所
- 認証は可能な限りManaged Identity:Azure資源間はマネージドIDで。サービスプリンシパルを使う場合は有効期限・権限スコープの最小化。
- 機密はKey Vault:クライアントシークレットやトークンはKey Vault参照を徹底。パイプライン内に平文を残さない。
- ログの秘匿:トークン・個人情報を扱うアクティビティは
secureInput・secureOutputを有効化して出力マスク。 - ネットワーク隔離:Private Endpoint/FirewallでAPIやストレージの到達範囲を限定。
- 最小権限:アプリ登録のスコープやRBACを用途ごとに分離。運用用・検証用を分ける。
性能・スケーラビリティ
- Copyの並列度:REST→ADLSのコピーはページ単位・パーティション単位で並列化しやすい。オフセット分割/IDレンジ分割でスループット向上。
- スロットリング対策:APIが429/503を返す場合に備えて、指数バックオフと最大リトライ回数を設計。サーバ側のレート制限に合わせてスロットリング。
- Web Activityは軽量運用:大きな本文や多数並列は非効率。必要最小限のフィールドのみ取得し、データ転送はCopyへ委譲。
コストの考え方
- データ移動課金:Copy Activityはデータ量と処理能力に比例した課金。大容量はCopyを選ぶ方が経済的。
- オーケストレーション課金:Web Activityは制御コストのみ。通知や状態確認のような小粒処理はWebの独壇場。
- 外部計算の活用:ロジックが複雑・変動が激しい場合はAzure Functions/Logic Apps側に寄せ、ADFは制御とデータ移動に専念。
監視・運用・テレメトリ
- パイプラインRunの可観測性:アクティビティ単位で所要時間・データ量・ステータスをトラック。Copyの失敗行復旧や再実行を前提に設計。
- メトリクスのダッシュボード化:日次件数、エラーコードの内訳、ページング回数などをLog AnalyticsやStorageに送出し可視化。
- エラー通知:失敗時のみTeams/WebhookをWeb Activityで送付。失敗パターン別のメッセージを用意。
よくある落とし穴と回避策
| 落とし穴 | 症状 | 回避策 |
|---|---|---|
| Webで大容量を取得 | 応答サイズ超過や再実行が不安定 | Copyに委譲してページング・並列を活用。Webは制御に限定。 |
| アクセストークンの漏えい | 出力ログにトークンが表示 | secureOutput必須。トークンはKey Vault参照、変数にも最小限。 |
| 時刻境界の取りこぼし | 更新の一部が欠落 | 数分のオーバーラップ取得+シンク側重複排除の二段構え。 |
| ページング仕様の誤解 | 最終ページで停止せずループ | 次ページURL/トークンの空判定を厳密化。Copyのページング規則を使用。 |
| リトライなしの一発勝負 | 一時的5xx/429で即失敗 | アクティビティのリトライ設定+指数バックオフ+サーバ側レート制限に従う。 |
パターン別のレファレンス設計
パターンA:REST→Data Lake(毎日数GB)
- REST LSでベースURL・認証を構成(Managed Identity推奨)。
- Datasetで相対URL・クエリをパラメータ化(開始日・終了日・ページサイズ)。
- Copyでページング+ForEach分割(IDレンジ/日付レンジ)。
- シンクはADLS Gen2のRaw層。ファイル名に抽出日とページ番号を付与。
- 後段でMapping Data FlowやSparkで整形。
パターンB:外部ジョブの起動&完了待ち
- Web Activityで
POST /jobsを呼び出し、jobIdを取得。 - Untilアクティビティで
GET /jobs/{jobId}を定期ポーリング(成功/失敗/タイムアウトの分岐)。 - 完了後に次の工程(コピーや通知)へ。
パターンC:通知・アラート
- エラー時のみ、Web ActivityでWebhookにペイロード送信。
- エラー種別・CorrelationId・実行リンクなどを本文に含める。
設計チェックリスト(運用に耐える品質へ)
- 接続はREST LSに集約し、Key Vault参照・マネージドIDで無人化。
- Copyのページング・並列化・再実行性を前提に、分割キー(ID/日付)を設計。
- Webは制御用途に限定。レスポンスは最小限を取り込み、本文は必要ならストレージへ。
- リトライ戦略(回数・間隔・上限)とスロットリング対応を明文化。
- 監査・メトリクスを残し、アラート・ダッシュボードを整備。
表:REST LSとWeb Activityの使い分け早見表
| 判断ポイント | 推奨 | 理由 |
|---|---|---|
| 大量データの連続取り込み | REST LS + Copy | ページング・並列で高スループット。 |
| 外部サービスの起動・通知 | Web Activity | 軽量でシンプル、分岐に強い。 |
| 共通の認証定義を複数で使いたい | REST LS | 鍵の一元管理・再利用性。 |
| 単発のGETで小さな設定値を取得 | Web Activity | レスポンスをそのまま次へ渡せる。 |
| OAuth2クライアント資格情報での機械連携 | REST LS | 運用・セキュリティ両面で安定。 |
実践Tips:式とパラメータのレシピ集
- ヘッダーの動的設定:
@{concat('Bearer ', variables('accessToken'))} - ファイル名に時刻を含める:
@{formatDateTime(utcNow(),'yyyyMMdd_HHmmss')} - 分岐:
@equals(activity('StartJob').output.statusCode, 202) - 空チェック:
@empty(activity('GetPage').output.body.next)
FAQ
Web ActivityだけでAPIからCSVをダウンロードして保存できますか?
技術的には本文を受け取りストレージに書く処理を組めますが、サイズや安定性の観点でCopy Activityに委譲するのが定石です。Copyはリトライ・ページング・並列・スループットで優位です。
REST LSとWeb Activityは併用できますか?
はい。例えばWebでジョブを起動→完了後にREST+Copyで結果を一括取得、といったハイブリッド構成は実務でよく使います。
OAuth2の認可コードフローは扱えますか?
ユーザー操作を伴うフローはADFには不向きです。サーバ間のクライアント資格情報フローやManaged Identityを選びましょう。
最終結論
データ転送ならREST Linked Service(+Copy)、制御ロジックならWeb Activity。この大原則に、データ量・認証・再利用性・保守性の観点を重ねて最適化すれば、ADFのAPI連携は速く、堅牢で、運用しやすい仕上がりになります。迷ったら本記事のチェックリストと早見表で判断し、まずは小さく作って性能と運用の数字を確認しながら設計を磨き込んでください。

コメント