もう技術選定や設計に悩まない!?全部入りフルスタックTypeScriptフレームワークAdonisJS - バリデーション編
前回の記事では、AdonisJSのLucid ORMを使用したデータベース操作について解説しました。マイグレーションの作成、モデルの定義、コントローラでのデータ操作方法を学び、データベースとアプリケーションを連携させる基本を押さえました。
今回は、バリデーション(データ検証) について詳しく解説します。アプリケーションにおいて、ユーザーからの入力を適切に検証することは、セキュリティやデータの整合性を保つ上で非常に重要です。AdonisJS v6 では、バリデーションライブラリとして VineJS が標準で組み込まれており、追加のインストールや設定は不要です。VineJSを活用することで、型安全なスキーマバリデーションを簡単に実装できます。
1. VineJSとは?
VineJSは、AdonisJS v6に統合されたバリデーションライブラリであり、スキーマベースのバリデーションを提供します。入力データの整形やカスタムバリデーションルールの作成にも対応しており、安全で堅牢なデータ処理を実現できます。
また、高速なバリデーションを実現するために最適化されています。公式のベンチマークによると、VineJSはZodやYupといった他のバリデーションライブラリと比較して、より優れたパフォーマンスを発揮します。
このパフォーマンスの高さにより、大量のリクエストが発生する環境でも、スムーズなデータ処理が可能になります。
2. バリデータの作成
AdonisJSでは、バリデータをコマンドで作成できます。以下のコマンドを実行すると、app/validators/
ディレクトリ内にバリデーションファイルが生成されます。
node ace make:validator post
これにより、app/validators/post.ts
が作成されます。
バリデータの定義
バリデーションスキーマでは、vine.object({...})
を使ってデータの形式を定義し、それぞれのフィールドに適切なルールを適用します。例えば、vine.string().trim().minLength(6)
は、文字列をトリム(前後の空白を削除)し、最低6文字以上であることを保証します。vine.string().trim().escape()
は、文字列内のHTMLエンティティをエスケープします。
import vine from '@vinejs/vine'
/**
* Postのcreateアクションをバリデーションします
*/
export const createPostValidator = vine.compile(
vine.object({
title: vine.string().trim().minLength(6),
content: vine.string().trim().escape()
})
)
/**
* Postのupdateアクションをバリデーションします
*/
export const uupdatePostValidator= vine.compile(
vine.object({
title: vine.string().trim().minLength(6),
content: vine.string().trim().escape()
})
)
3. コントローラでバリデーションを適用
コントローラ内で request.validateUsing()
を使用することで、リクエストデータに対してバリデーションを適用できます。これにより、クライアントからの不正なデータを事前にフィルタリングし、アプリケーションの安定性やセキュリティを強化できます。
バリデーションが成功すると、リクエストデータが処理され、データベースに保存されます。逆に、バリデーションに失敗した場合は 422 Unprocessable Entity
のレスポンスが自動的に返され、適切なエラーメッセージがクライアントに通知されます。
import type { HttpContext } from '@adonisjs/core/http'
import Post from '#models/post'
import { createPostValidator, updatePostValidator } from '#validators/post'
export default class PostsController {
async store({ request, response }: HttpContext) {
const data = await request.validateUsing(createPostValidator)
const post = await Post.create(data)
return response.json(post)
}
async update({ params, request, response }: HttpContext) {
const post = await Post.findOrFail(params.id)
const data = await request.validateUsing(updatePostValidator)
post.merge(data)
await post.save()
return response.json(post)
}
}
4. バリデーションの動作確認
バリデーションエラーの例(タイトルが短すぎる)
curl -X POST http://localhost:3333/posts \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{"title": "short", "content": "Test content"}' | jq
レスポンス例:
{
"errors": [
{
"message": "The title field must have at least 6 characters",
"rule": "minLength",
"field": "title",
"meta": {
"min": 6
}
}
]
}
成功例
curl -X POST http://localhost:3333/posts \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{"title": "Valid Title", "content": "This is valid content."}' | jq
成功レスポンス例:
{
"title": "Valid Title",
"content": "This is valid content.",
"createdAt": "2025-02-27T14:36:33.004+00:00",
"updatedAt": "2025-02-27T14:36:33.004+00:00",
"id": 7
}
5. まとめ
この記事では、AdonisJS v6のVineJSを使用したバリデーション処理の実装方法について解説しました。
次回はフロントエンド(Inertia + React)側の実装について解説します!
Discussion