英語?日本語?マイクロサービスのエラーメッセージは何語が良い?

プログラミング#マイクロサービス#多言語#エラーメッセージ
suin
suin
2015年10月14日 投稿
image.png (176.9 kB)

マイクロサービスがREST APIを提供するようなアーキテクチャを組んだ場合でも、
マイクロサービスで発生したエラーをエンドユーザに何らかの形を通知する必要があります。

技術的なシステムエラーであれば詳しく通知しないこともありますが、
「購入しようとした商品がちょうど売り切れてしまって購入できなかった」といったようなドメインエラーは、
必要十分にユーザに知らせる必要が出てきます。

特に、多言語対応・地域対応まで念頭におくと、翻訳もしなければなりません。
では、翻訳の責務はマイクロサービスのサーバ・クライアントどちらにあるのでしょうか?

2.png (70.0 kB)

正解はシステムによって様々だと思います。
ここでは、システムが採用できそうな責務の分担パターンを5つ紹介したいと思います。

  1. モノリンガル
    1.マルチリンガル
  2. セマンティック
  3. フォーマットメッセージ
  4. ハイブリッドレスポンス

1. モノリンガル

英語など特定の言語のメッセージしか返さないサービス。翻訳の責務はクライアントが負う。

リクエスト例

http
POST /users HTTP/1.1
Host: account.services.example.com
Content-Length: 69
Content-Type: application/json; charset=utf-8

{
  "username": "a",
  "email": "foo@example.com",
  "password": "p@ssW0rd"
}

レスポンス例

http
HTTP/1.1 400 Bad Request
Content-Type: application/json; charset=UTF-8

{
  "message": "Username is too short (minimum is 3 characters)"
}

モノリンガルのメリット

  • サーバは、翻訳が不必要

モノリンガルのデメリット

  • クライアントは、翻訳が必要
  • クライアントは、自由な翻訳がしにくい(しようと思ったら、テキスト処理が必要)

2. マルチリンガル

クライアントのAccept-Languageにしたがって、言語を切り替えるサービス。
翻訳の責務はサーバが負う。
例えば、Facebook APIはユーザの言語設定を見て切り替えている。

リクエスト例

http
POST /users HTTP/1.1
Host: account.services.example.com
Content-Length: 69
Content-Type: application/json; charset=utf-8
Accept-Language: ja-JP,ja;q=0.9,en-US;q=0.7,en;q=0.5

{
  "username": "a",
  "email": "foo@example.com",
  "password": "p@ssW0rd"
}

レスポンス例

http
HTTP/1.1 400 Bad Request
Content-Type: application/json; charset=UTF-8
Content-Language: ja

{
  "message": "ユーザ名が短すぎます。(最低3文字)"
}

マルチリンガルのメリット

  • クライアントは、翻訳が不必要

マルチリンガルのデメリット

  • サーバは、ネゴシエーションの実装が必要
  • サーバは、クライアントの要請によって翻訳を増やす必要あり
  • クライアントは、自由な翻訳がしにくい(しようと思ったら、テキスト処理が必要)

3. セマンティック

特定の言語を返さず、エラーコードなど意味的なエラー情報のみを返すサービス。
翻訳の責務はクライアントが負う。

リクエスト例

http
POST /users HTTP/1.1
Host: account.services.example.com
Content-Length: 69
Content-Type: application/json; charset=utf-8

{
  "username": "a",
  "email": "foo@example.com",
  "password": "p@ssW0rd"
}

レスポンス例

http
HTTP/1.1 400 Bad Request
Content-Type: application/json; charset=UTF-8

{
  "code": "username.too_short",
  "values": {
    "minimum": "3"
  }
}

クライアントは、username.too_short → 日本語「ユーザ名は{minimum}文字以下にしてください」といったマップを持っている。

セマンティックのメリット

  • サーバは、翻訳を持たなくていい
  • クライアントは、自由な翻訳が可能

セマンティックのデメリット

  • クライアントは、必ず翻訳を持つ必要がある
  • クライアントは、翻訳のエンジンを実装しないとならない
  • クライアントは、サーバがメッセージオブジェクトを追加したら、すぐに対応しないといけない

4. フォーマットメッセージ

モノリンガルと同じく英語など特定の言語のメッセージしか返さないが、テキスト処理を容易にした中間的なメッセージオブジェクトを返すサービス。
翻訳の責務はクライアントが負う。

リクエスト例

http
POST /users HTTP/1.1
Host: account.services.example.com
Content-Length: 69
Content-Type: application/json; charset=utf-8

{
  "username": "a",
  "email": "foo@example.com",
  "password": "p@ssW0rd"
}

レスポンス例

http
HTTP/1.1 400 Bad Request
Content-Type: application/json; charset=UTF-8

{
  "message": "Username is too short (minimum is {{minimum}} characters)",
  "values": {
    "minimum": "3"
  }
}

フォーマットメッセージのメリット

  • サーバは、翻訳が不必要
  • クライアントは、翻訳に自由度がある
  • クライアントは、翻訳がなくても英語(もしくはサービスデフォルトの言語)をフォーマットすることで出力できる

フォーマットメッセージのデメリット

  • クライアントは、翻訳が必要
  • クライアントは、翻訳のエンジンを実装しないとならない

5. ハイブリッドレスポンス

最終的な翻訳の責務はクライアントが負うが、
翻訳の自由度、翻訳をしないという選択の自由をクライアントに与えるサービス。モノリンガル・セマンティック・フォーマットメッセージを組み合わせたもの。

リクエスト例

http
POST /users HTTP/1.1
Host: account.services.example.com
Content-Length: 69
Content-Type: application/json; charset=utf-8

{
  "username": "a",
  "email": "foo@example.com",
  "password": "p@ssW0rd"
}

レスポンス例

http
HTTP/1.1 400 Bad Request
Content-Type: application/json; charset=UTF-8

{
  "code": "username.too_short",
  "message": "Username is too short (minimum is 3 characters)",
  "format": "Username is too short (minimum is {{minimum}} characters)",
  "values": {
    "minimum": "3"
  }
}

ハイブリッドレスポンスのメリット

  • サーバは、翻訳が不必要
  • クライアントは、翻訳に自由度がある
  • クライアントは、翻訳がなくても英語(もしくはサービスデフォルトの言語)をそのまま出すことができる

ハイブリッドレスポンスのデメリット

  • クライアントは、翻訳が必要
  • クライアントは、翻訳のエンジンを実装しないとならない
  • クライアントは、翻訳の方法が複数できてしまう
  • サーバは、3つのデータを作らないとならない

翻訳データプロバイダ

セマンティックメッセージやフォーマットメッセージはクライアントが翻訳する必要があるというデメリットがある。
翻訳データプロバイダは、クライアントが翻訳エンジンを実装するコストを抑えるために、サーバが協力する補助的な仕組み。

例えば、セマンティックの場合、サーバはエラーコードと翻訳のマップをHTTPで公開・提供する。
クライアントはHTTP経由でサーバの翻訳データリソースにアクセスし、ダウンロードでき、
その翻訳マップをデフォルトとして利用することができる。

まとめ

マイクロサービスでエラーメッセージの翻訳の責務をどうしたらいいかについて、いくつかパターンを整理してみました。

どれが正解というわけではないので、プロジェクトやシステムに合ったものを採用するといいかと思います。