ホームページ > 記事 > ウェブフロントエンド > スキーマ検証のための VineJS と Zod
オゲネテガ・デネド著✏️
データの整合性を維持し、アプリケーションでの予期せぬ動作を防ぐために、ユーザーまたはその他の外部ソースからのデータは事前定義された構造または形式に準拠する必要があるため、スキーマ検証は本番環境に対応したアプリには必須です。
通常、開発者は、ユーザーが Web サイトにフォームを送信するときの入力データ、または HTTP リクエスト経由で API に送信されるペイロードの検証を考え出す必要があります。ただし、この検証ロジックを手動で記述するのは繰り返しが多く時間がかかるため、開発者の生産性は良くありません。
幸いなことに、一般的な開発タスク用のライブラリは JavaScript コミュニティ内でほとんど問題になっておらず、スキーマ検証も例外ではありません。
この記事では、VineJS と Zod の検証機能、パフォーマンス、ツールとの統合、エコシステムを評価して比較します。最後には、VineJS がパフォーマンスで優れている一方で、Zod の多用途性と強力な TypeScript 統合により、ほとんどのプロジェクトにとって Zod がより包括的な選択肢となっていることがわかります。
VineJS は、軽量で使いやすく、パフォーマンスが高いように設計された最新の JavaScript/TypeScript スキーマ検証ライブラリです。
このプロジェクトは AdonisJS バリデーター コードベースから生まれ、アップグレードされ、スタンドアロン ライブラリとしてリリースされました。 VineJS は、Node.js サーバー側環境、特に API への受信リクエストを検証してペイロードが予期された形式であることを確認してからさらに処理するようなシナリオで使用するために構築されました。
VineJS の主な機能には次のようなものがあります。
次のセクションでは、これらの機能の一部がどのように機能するかを見ていきます。
VineJS のスキーマ検証機能のいくつかを見てみましょう。
ユーザー入力や外部ソースからのデータを扱う場合、多くの場合、文字列、数値、ブール値などの基本的なデータ型を検証することが最初のステップとなります。 VineJS は、直感的な API を使用してこのプロセスを簡素化します。
たとえば、ユーザーの年齢を検証してみましょう:
import vine, { errors } from "@vinejs/vine"; // NOTE: VineJS is ESM only const ageSchema = vine.number().min(18).max(30); try { const output = await vine.validate({ schema: ageSchema, data: 21 }); console.log(output); } catch (error) { if (error instanceof errors.E_VALIDATION_ERROR) { console.log("validation error: age is invalid"); } else { console.log("an unexpected error occurred"); } }
この例では、入力が数値であることを確認するための単純なスキーマを作成し、min メソッドと max メソッドを使用して入力が 18 から 30 の間にあることを確認しました。VineJS は、検証をより正確にするために、これらの追加の検証ルールを提供します。
場合によっては、検証ルールを適用する前に入力データをフォーマットする必要があります。たとえば、検証前に入力文字列が確実に小文字に変換されるようにしたい場合は、スキーマ内でこれを行うことができます:
const usernameSchema = vine .string() .toLowerCase() .minLength(3) .maxLength(15) .regex(/^[a-z0-9_]+$/); console.log(vine.validate({schema: nameSchema, data: "Bruce_Wayne"})) // logs bruce wayne
このスキーマでは、ユーザー名は長さと形式をチェックする前に小文字に変換されます。
VineJS は基本的なスキーマ タイプに加えて、オブジェクトと配列の検証を提供するため、複数のフィールドを持つフォームや API ペイロードの検証に特に役立ちます。
ユーザーのプロフィールを表すオブジェクトを検証する方法を見てみましょう:
const userProfileSchema = vine.object({ name: vine.string().minLength(3), email: vine.string().email(), age: vine.number().min(18).max(65).optional(), }); const output = await vine.validate({ schema: ageSchema, data: { name: "Jane Doe", email: "jane.doe@example.com", age: 29, }, }); // logs { name: 'Jane Doe', email: 'jane.doe@example.com', age: 29 }
この例では、名前、電子メール、年齢のフィールドを含むユーザー プロファイルのスキーマを設定しました。
vine.object() メソッドを使用すると、指定されたルールに従って各フィールドを検証できます。 vine.object 内のすべてのフィールドはデフォルトで必須であるため、検証されるオブジェクト内に存在する必要があります。ただし、optional() メソッドを使用して age フィールドをオプションとしてマークしているため、このフィールドが欠けていても検証は失敗しません。
配列も同様に処理できます:
const tagsSchema = vine .array(vine.string().minLength(2).maxLength(20)) .minLength(1) .maxLength(10); console.log( await vine.validate({ schema: tagsSchema, data: ["tech", "news", "coding"], }) ); // logs [ 'tech', 'news', 'coding' ]
この例では、スキーマにより、配列内の各項目が 2 ~ 20 文字の長さの文字列であることが保証され、配列自体には 1 ~ 10 個の要素が含まれている必要があります。これは、タグやカテゴリなどのリストを検証する場合に特に便利です。
プリコンパイルは、スキーマを最適化された JavaScript 関数に変換する VineJS の重要な機能で、検証に再利用できるため、スキーマの解析と検証を繰り返すオーバーヘッドを削減できます。これは、実稼働環境でパフォーマンスを向上させるために非常に役立ちます。
スキーマをプリコンパイルするには、vine.compile() メソッドを使用できます。
const compiledSchema = vine.compile( vine.object({ username: vine.string().minLength(3).maxLength(30), password: vine.string().minLength(8), }) ); // Use the compiled schema to validate data console.log( await compiledSchema.validate({ username: "janedoe", password: "password123", }) );
プリコンパイルは、トラフィックの多い API エンドポイントのスキーマなど、頻繁に検証が必要なスキーマに特に役立ちます。
スキーマは再利用可能な関数にコンパイルされるため、スキーマの解析と検証の繰り返しのプロセスが不要になり、VineJS が検証プロセスを高速化してアプリケーションの応答性を高めることができます。
カスタム エラー メッセージを使用すると、ユーザーにより明確なフィードバックが提供され、間違いの特定と修正が容易になります。 VineJS は、組み込みの SimpleMessagesProvider API を使用して、エラー メッセージをキーと値のペアとして定義します。キーはルール名 (必須、文字列、または特定のフィールドとルールの組み合わせ) にすることができ、値は対応するエラー メッセージです。
SimpleMessagesProvider API は、グローバルに、スキーマごとのレベルで、または validate メソッドが呼び出されたときに構成できます。以下のコード例では、API をグローバルに使用します。
たとえば、ユーザー名と電子メールフィールドのエラーメッセージをカスタマイズしたいとします。
import vine, { errors } from "@vinejs/vine"; // NOTE: VineJS is ESM only const ageSchema = vine.number().min(18).max(30); try { const output = await vine.validate({ schema: ageSchema, data: 21 }); console.log(output); } catch (error) { if (error instanceof errors.E_VALIDATION_ERROR) { console.log("validation error: age is invalid"); } else { console.log("an unexpected error occurred"); } }
ネストされたフィールドまたは配列要素のメッセージをカスタマイズすることもできます。ネストされたフィールドの場合は、ドット表記を使用します:
const usernameSchema = vine .string() .toLowerCase() .minLength(3) .maxLength(15) .regex(/^[a-z0-9_]+$/); console.log(vine.validate({schema: nameSchema, data: "Bruce_Wayne"})) // logs bruce wayne
配列要素の場合、ワイルドカード (*) を使用してすべての項目をターゲットにするか、インデックスを指定できます。
const userProfileSchema = vine.object({ name: vine.string().minLength(3), email: vine.string().email(), age: vine.number().min(18).max(65).optional(), }); const output = await vine.validate({ schema: ageSchema, data: { name: "Jane Doe", email: "jane.doe@example.com", age: 29, }, }); // logs { name: 'Jane Doe', email: 'jane.doe@example.com', age: 29 }
VineJS では、フィールド名をより使いやすいラベルに置き換えることもできます。これは、コード内のフィールド名がユーザー向けメッセージに適していない場合に役立ちます:
const tagsSchema = vine .array(vine.string().minLength(2).maxLength(20)) .minLength(1) .maxLength(10); console.log( await vine.validate({ schema: tagsSchema, data: ["tech", "news", "coding"], }) ); // logs [ 'tech', 'news', 'coding' ]
VineJS では、組み込みルールが提供する機能を超えて、開発者が特定のニーズを満たすカスタム検証ルールを作成できるようになります。これらのカスタム ルールをプロジェクトで使用するには、スタンドアロン関数として実装するか、既存のスキーマ クラスに統合します。
VineJS では、カスタム ルールは単にフィールドの値を更新または検証する関数です。通常、関数には 3 つのパラメータ (検証される値、ルールに必要なオプション、およびフィールド コンテキスト) が渡されます。
たとえば、文字列が有効な MongoDB ObjectId かどうかをチェックする mongodbId というカスタム ルールを作成してみましょう。
const compiledSchema = vine.compile( vine.object({ username: vine.string().minLength(3).maxLength(30), password: vine.string().minLength(8), }) ); // Use the compiled schema to validate data console.log( await compiledSchema.validate({ username: "janedoe", password: "password123", }) );
このルールを VineJS スキーマ内で使用できるようにするには、まず vine.createRule メソッドを使用してルールを VineJS 互換のルールに変換する必要があります。
import vine, { SimpleMessagesProvider } from '@vinejs/vine'; vine.messagesProvider = new SimpleMessagesProvider({ 'required': 'You must provide a value for {{ field }}.', 'email': '{{ field }} needs to be a valid email address.', 'username.required': 'A username is required to continue.', });
使用法をさらに簡素化するには、mongodbId メソッドを VineString クラスに直接追加して、チェーン可能な API を活用するとよいでしょう。
Zod は、シンプルかつ強力な TypeScript ファーストのスキーマ検証ライブラリです。これにより、データ構造と検証ルールの定義と適用が容易になり、フロントエンド アプリケーションとバックエンド アプリケーションの両方でうまく機能します。
Zod は TypeScript 専用に設計されており、TypeScript プロジェクトのスムーズな統合と強力な型推論を保証します。
Zod の主な機能の一部は次のとおりです:
Zod はスキーマ検証を簡単かつ柔軟にし、さまざまなデータ型と検証ニーズを簡単に処理できるようにします。以下のセクションでわかるように、その構文は VineJS に非常に似ています。
Zod は、文字列、数値、ブール値、日付などの基本的なデータ型を適切に処理します。
たとえば、文字列と数値を検証するための簡単なスキーマを作成してみましょう。
import vine, { errors } from "@vinejs/vine"; // NOTE: VineJS is ESM only const ageSchema = vine.number().min(18).max(30); try { const output = await vine.validate({ schema: ageSchema, data: 21 }); console.log(output); } catch (error) { if (error instanceof errors.E_VALIDATION_ERROR) { console.log("validation error: age is invalid"); } else { console.log("an unexpected error occurred"); } }
この例では、nameSchema は「Peter Parker」が文字列であることを検証して合格しますが、年齢が 18 歳未満であるため ageResult は失敗します。
オブジェクトや配列を扱う場合、Zod を使用するとデータの形状を簡単に定義できます。たとえば、ユーザー オブジェクトとタグのリストの検証は次のように行うことができます:
const usernameSchema = vine .string() .toLowerCase() .minLength(3) .maxLength(15) .regex(/^[a-z0-9_]+$/); console.log(vine.validate({schema: nameSchema, data: "Bruce_Wayne"})) // logs bruce wayne
上記の例では、userSchema はユーザー データを検証し、tagSchema は配列に文字列のみが含まれていることを確認します。 123 は文字列ではないため、配列の検証は失敗します。
検証フィードバックをより便利にし、エラーの認識を簡単にするために、Zod は構成可能なエラー メッセージもサポートしています。
たとえば、年齢が 18 歳未満の場合は、パーソナライズされたメッセージを設定できます。
const userProfileSchema = vine.object({ name: vine.string().minLength(3), email: vine.string().email(), age: vine.number().min(18).max(65).optional(), }); const output = await vine.validate({ schema: ageSchema, data: { name: "Jane Doe", email: "jane.doe@example.com", age: 29, }, }); // logs { name: 'Jane Doe', email: 'jane.doe@example.com', age: 29 }
ここでは、検証が失敗し、カスタム エラー メッセージ「18 歳以上である必要があります。」とともにエラーがスローされます。
Zod は、refine メソッドを使用してカスタム検証ロジックを作成する柔軟性を提供します。これにより、基本的な型チェックを超えたルールを適用できます。
たとえば、16 進数のカラー コードを検証するには、それが文字列であるかどうかを単に判断するだけでは十分ではありません。また、特定のパターンに従う必要もあります。その方法は次のとおりです:
const tagsSchema = vine .array(vine.string().minLength(2).maxLength(20)) .minLength(1) .maxLength(10); console.log( await vine.validate({ schema: tagsSchema, data: ["tech", "news", "coding"], }) ); // logs [ 'tech', 'news', 'coding' ]
この例では、文字列が 3 文字または 6 文字で構成される有効な 16 進カラー コード (#RGB または #RRGGBB) であるかどうかを判断するために、refine メソッドを使用してカスタム検証ロジックが追加されます。
VineJS ドキュメントのベンチマークは、VineJS が Node.js エコシステム内で最も高速な検証ライブラリの 1 つであり、単純なオブジェクト検証やその他の検証において Yup や Zod を上回っていることを示しています。
VineJS ドキュメントに示されているとおり。
このグラフは、VineJS が優れたパフォーマンスを提供し、高いパフォーマンスを必要とするバックエンド アプリケーションにとって優れたソリューションであることを示しています。 Zod はうまく機能し、ほとんどのユースケースで十分な速度を示します。
TypeScript のサポートは両方とも優れていますが、Zod は型推論をよりシームレスにするために TypeScript を念頭に置いて設計されました。 VineJS も TypeScript をサポートしていますが、それほど深く統合されていないため、TypeScript を多用するプロジェクトにとっては Zod がわずかに有利です。
より多くのリソース、チュートリアル、プラグインが利用できるため、Zod にはより大規模で確立されたコミュニティがあります。ただし、VineJS は新しく、リソースが少なく、コミュニティも小さいにもかかわらず、使いやすい API とパフォーマンス重視の設計により、さらに成長すると予想されています。
VineJS を使用する主な欠点は、VineJS がフロントエンド ランタイムで使用するように設計されていないことです。この制約のため、クライアント側の検証を必要とするアプリケーションにはあまり適していません。さらに、CommonJS はサポートされていないため、CommonJS を使用するプロジェクトでは問題になる可能性があります。これは ECMAScript モジュール (ESM) でのみ機能します。
ただし、Zod はより汎用性が高く、2 つの主要な JavaScript モジュール システムをサポートしながら、コードを実行している環境に関係なく適切に動作するため、フルスタック プロジェクトに適しています。
VineJS と Zod 以外にも、スキーマ検証用の他のライブラリがいくつかあり、さまざまな使用例について言及する価値があります。
Yup はその使いやすさから好評で、特に React や Formik などのツールと組み合わせた場合に、フロントエンドの検証で頻繁に使用されます。 VineJS や Zod と比較すると、複雑な構造ではうまく機能しない可能性がありますが、チェーン可能な API によりスキーマの開発が簡単になります。
Node.js バックエンドでよく使用される強力なライブラリは joi と呼ばれます。その API は VineJS や Zod の軽量アプローチよりも重く感じることがありますが、柔軟性が高く、深くネストされたオブジェクトの複雑な検証を管理します。高度な検証を必要とするサーバー側アプリには最適です。
速度と完全な JSON スキーマへの準拠は、AJV の主な優先事項です。 Zod や VineJS のようなユーザーフレンドリーな API はありませんが、特に API での JSON データの検証には最適です。ただし、巨大な JSON データセットの検証など、高い効率が必要なタスクには理想的です。
VineJS と Zod は 2 つの優れたスキーマ検証ツールであり、どちらを使用しても間違いはありませんが、異なる領域で優れています。どちらを使用するかまだわからない場合は、小規模なプロジェクトで両方を試して、どちらが適切であるかを確認してください。コーディングを楽しんでください!
コードのデバッグは常に面倒な作業です。しかし、間違いを理解すればするほど、修正が容易になります。
LogRocket を使用すると、これらのエラーを新しい独自の方法で理解できます。当社のフロントエンド監視ソリューションは、JavaScript フロントエンドに対するユーザーの関与を追跡し、エラーを引き起こしたユーザーの行動を正確に確認できるようにします。
LogRocket は、コンソール ログ、ページの読み込み時間、スタック トレース、ヘッダー本体を含む遅いネットワーク リクエスト/レスポンス、ブラウザーのメタデータ、カスタム ログを記録します。 JavaScript コードの影響を理解するのがこれまでになく簡単になります!
無料でお試しください。
以上がスキーマ検証のための VineJS と Zodの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。