SymfonyでAPI向けにカスタムエラーメッセージを返す方法を解説!初心者でも安心のバリデーション基礎
生徒
「SymfonyでAPIを作っているんですが、バリデーションエラーのときに、もっと分かりやすいメッセージを返したいです。」
先生
「Symfonyでは、バリデーション時にカスタムメッセージを設定して、APIのレスポンスとして返すことができますよ。」
生徒
「どうやって設定するんですか?初心者なので、簡単に教えてください!」
先生
「もちろんです。それでは、API向けにわかりやすいエラーを返す方法を、やさしく解説していきましょう!」
1. Symfonyのバリデーションとは?
Symfony(シンフォニー)では、データが正しいかどうかをチェックするバリデーションという仕組みがあります。例えば、名前が空欄になっていないか、メールアドレスの形式が正しいかなどを検査します。
Symfonyのバリデーションは、Validatorコンポーネントという機能を使って行います。この機能は、フォームからのデータだけでなく、APIから送られてくるデータにも使うことができます。
2. エラーが英語でわかりにくい?カスタムメッセージで解決!
Symfonyのバリデーションエラーは、初期設定だと英語で表示されます。たとえば「This value should not be blank(この値は空であってはいけません)」というようなメッセージです。
ですが、APIを作るときには、日本語で、ユーザーに分かりやすい説明を返すことが大切です。そのためには、カスタムエラーメッセージを設定しましょう。
3. APIで使うエンティティにバリデーションとメッセージをつけよう
まずは、バリデーションを使う対象のエンティティ(例えばUserなど)に、カスタムメッセージを付けてみましょう。以下は名前とメールアドレスの例です。
use Symfony\Component\Validator\Constraints as Assert;
class User
{
/**
* @Assert\NotBlank(message="名前を入力してください。")
*/
private $name;
/**
* @Assert\Email(message="正しいメールアドレス形式で入力してください。")
*/
private $email;
}
@Assert\NotBlankは「空欄ではいけない」ことを意味し、messageでカスタムエラーメッセージを設定できます。これによって、英語ではなく「名前を入力してください。」というメッセージが返るようになります。
4. バリデーションエラーをAPIレスポンスとして返すには?
APIでは、フォームに表示するのではなく、JSON形式でエラーを返す必要があります。そこで、バリデーションエラーをチェックして、JSONで返す処理を書いてみましょう。
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Validator\Validator\ValidatorInterface;
public function register(Request $request, ValidatorInterface $validator): JsonResponse
{
$user = new User();
$user->setName($request->get('name'));
$user->setEmail($request->get('email'));
$errors = $validator->validate($user);
if (count($errors) > 0) {
$errorMessages = [];
foreach ($errors as $error) {
$errorMessages[$error->getPropertyPath()] = $error->getMessage();
}
return new JsonResponse([
'status' => 'error',
'errors' => $errorMessages,
], 400);
}
// 通常処理...
return new JsonResponse(['status' => 'ok']);
}
このコードでは、バリデーションに失敗した項目ごとに、カスタムメッセージを取り出してJSONとして返しています。これでAPIを利用する側にとっても、とても分かりやすくなります。
5. 実際の出力例を見てみよう
例えば、名前が空で、メールアドレスの形式が間違っていたとします。そのときの出力結果は以下のようになります。
{
"status": "error",
"errors": {
"name": "名前を入力してください。",
"email": "正しいメールアドレス形式で入力してください。"
}
}
このように、フィールド名をキーとして、エラーメッセージが日本語で返ってくるので、フロントエンド側でも扱いやすくなります。
6. バリデーションルールの種類とカスタムメッセージの例
Symfonyのバリデーションには他にも様々な種類があります。以下に主なものと、それぞれのカスタムメッセージの例を紹介します。
- NotBlank:空であってはいけない
- Email:メール形式であるべき
- Length:文字数の長さ制限
- Regex:正規表現に一致する必要がある
/**
* @Assert\Length(
* min=8,
* minMessage="パスワードは最低でも{{ limit }}文字必要です。"
* )
*/
private $password;
このように、パラメータを埋め込んだカスタムメッセージも可能です。{{ limit }}のような記述が、自動で数字に置き換わります。
7. APIレスポンスの形式は統一しよう
バリデーションエラーだけでなく、成功時やサーバーエラー時も含めて、APIレスポンスの形式を統一しておくと便利です。たとえば、常にstatusというキーを含めるなどのルールを決めておくことで、フロントエンドの実装もシンプルになります。