コンテンツは常に更新され、そのたびに提供中のすべてのロケールへ届ける必要があります。トレーニングモジュールに新しいレッスンが追加される。CMS のエントリが保存される。商品説明が編集される。そんなとき、翻訳はドイツ語、フランス語、日本語、さらに十数言語へ一斉に展開されるべきであり、その間もアプリが待たされるべきではありません。
非同期ローカライゼーションAPIは、まさにその瞬間のために設計されています。1回のリクエストで、全ロケールへ。結果は完了したものから届く。 対象ロケールと一緒にコンテンツを一度 POST すれば、すぐに 202 が返り、プラットフォームが各ロケールを独立したバックグラウンドジョブとして翻訳します。用語集、ブランドボイス、モデル設定はそのまま。使われるのは 同期API と同じエンジンです。そして再試行を自前で持つ必要はなくなります。
このページの内容
課題#
トレーニングプラットフォーム、コンテンツ管理システム、eラーニングツールでは、コンテンツが作成または更新された瞬間に、何十もの言語へ翻訳する必要がよくあります。同期ローカライゼーションAPI でも対応はできますが、規模が大きくなるとトレードオフが発生します。
たとえば、英語で作成されたトレーニングモジュールを14言語の学習者に届ける必要があるとします。同期APIでは選択肢が2つありますが、どちらにもコストがあります。
14本の並列リクエストを投げる – 対象ロケールごとに1リクエストずつ、同じソースペイロードを載せて送ります。各言語は返ってきた時点で表示できますが、重複データを含む14回分のネットワーク往復を管理する必要があり、そのうち1つが失敗したときの再試行ロジックも自分で持たなければなりません。
14言語すべてを1回の同期呼び出しで翻訳する – 往復回数は減りますが、今度は最も遅いロケールが終わるまで、どの言語も表示できません。
どちらの方法でも、翻訳処理のあいだアプリケーションは縛られます。サーバーが処理途中で再起動すれば、進行中の翻訳は失われます。1つの言語が失敗した場合、部分的な失敗への対応は自分で行う必要があります。しかも、翻訳が進行中であることをユーザーにわかりやすく伝える手段も得られません。
非同期APIは、このトレードオフを取り除きます。1回のリクエストで、対象ロケールごとに1つのジョブを持つジョブグループが作成されます。各ジョブは、耐久性のあるバックグラウンドワークフローとしてローカライゼーションエンジンを独立して通るため、あなたの側でサーバーが再起動しても何も失われません。処理はあなたのプロセス内で走っていないからです。結果は各ロケールの完了と同時に、そのロケール単位で配信されます。アプリは応答性を保ったまま。失敗は切り分けられ、再試行と配信はプラットフォームが担います。
ロケールが1つで、少し待てるなら? sync を使いましょう。
非同期APIが真価を発揮するのは、ロケール数が多いとき、コンテンツが長いとき、あるいは UI で進捗を見せたいときです。必要なのが単一のロケールペアで、1回の往復を待てるなら、同期 Localize エンドポイント のほうがシンプルです。1回のリクエストで翻訳済みデータがレスポンスとして返り、webhook エンドポイントを運用する必要もありません。ジョブが大きすぎる、遅すぎる、あるいはロケール数が多すぎて待てない。そんなときに非同期を選んでください。
仕組み#
ステップは3つ。ただし、あなたのリクエスト/レスポンスサイクル内で起こるのは最初の1つだけです。残りの2つはプラットフォーム上で、独立して進みます。
1回のリクエストを送信する
コンテンツと対象ロケールを /jobs/localization に POST します。API はペイロードを検証し、ロケールごとに1つのジョブを持つジョブグループを作成し、グループ ID とジョブ概要を含む 202 を返します。アプリケーションはそのまますぐに処理を続けられます。この呼び出しの中で翻訳は実行されません。リクエストとレスポンスの完全な形式は ジョブの作成 を参照してください。
プラットフォームが各ロケールを独立して処理する
完了したものから結果を受け取る
ロケールの処理が完了した瞬間に、プラットフォームはその結果をあなたの webhook URL に配信します。UI でライブ進捗を表示したいなら、たとえばジョブ完了に合わせて更新される「14件中3件完了」のようなカウンターのために、グループの WebSocket に接続してください。プル型にしたい場合は、一定間隔で グループをポーリング することもできます。
認証
すべてのリクエスト — REST と WebSocket の両方 — は、X-API-Key ヘッダーで認証します。キーは組織スコープで、その組織内のすべてのエンジンにアクセスできます。詳しくは Authentication を、キーの作成方法は API Keys を参照してください。
ジョブグループモデル#
1回の送信で生成されるのは、対象ロケールごとに1つの job を持つ1つの group です。この構造こそが全体を理解するための基本であり、難しい問いにも答えられる理由です。
勘の鋭い読者なら、すでにこう考えているはずです。あるロケールが失敗したらどうなるのか。そのあいだアプリはどうなるのか。この2つに、グループモデルが答えます。
- 失敗は切り分けられます。各ロケールがそれぞれ独立したジョブだからです。 たとえばドイツ語が成功し、日本語が失敗した場合でも、ドイツ語の翻訳は通常どおり配信され、日本語のジョブは独自の
errorMessageを持ちます。グループはpartialを報告し、成功した分はそのまま出荷できます。あるロケールでの失敗が、すでに完了した別のロケールをロールバックすることはありません。完全なステータス仕様は ジョブグループの追跡 にあります。 - 進行中の処理は再起動後も失われません。あなたのプロセス内で実行されていないからです。 各ジョブはプラットフォーム上の耐久性のあるバックグラウンドワークフローです。サーバーが再起動しても、進行中の処理が失われることはありません。再接続またはポーリングすれば、グループは中断前と同じ場所にあります。
- グループは、そのまま UI に結びつけられる進捗モデルです。
202からgroupIdを保存し、webhook 配信または WebSocket スナップショットをもとに進捗表示を動かします。「14言語中3言語が準備完了」は、グループ配下の子ジョブを数えたカウンターです。
このモデルには、正直に言えばコストもあります。同期呼び出しでは不要だった、少しの統合作業が必要です。結果を受け取るには HTTPS の webhook エンドポイントを運用するか、サーバーサイドで WebSocket を維持する必要があり、翻訳済みデータを1つのレスポンスからまとめて読む代わりに、各ロケールが届くたびに処理しなければなりません。その代わり、再試行・障害の切り分け・配信はプラットフォームが担い、アプリが翻訳待ちで止まることはありません。
それこそが、非同期APIが実現するために作られたトレードです。1回のリクエストで、全ロケールへ。結果は完了したものから届く。 次のページでは、その文を構成する操作を見ていきます。
