schemantic について
Schemanticは、再利用可能な実行時JSON Schemaに結び付いた型付きデータクラスを定義するDartライブラリです。JSON変換や検証に使えるコードを生成し、単独でもgenkit-dartと組み合わせても利用できます。
主な機能
- 01型付きデータクラスの生成
- 02JSONのシリアライズと解析
- 03実行時のJSON Schema参照
- 04プリミティブ・コレクションSchema
- 05ユニオン・再帰Schema
活用シーン
- 01JSONから型付きDartオブジェクトへの変換
- 02実行時の任意JSON検証
- 03アプリケーション内でのSchema再利用
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ genkit-ai/ genkit-dart --skill schemanticインストール後、Claude Code で/schemanticを入力して読み込まれたか確認します。
詳細
Schemantic
Schemantic は、強い型付けのデータクラスを定義し、再利用可能な実行時 JSON スキーマに自動的にバインドする汎用 Dart ライブラリです。genkit-dart フレームワークの標準ですが、単独でも使用できます。
コアコンセプト
強い型付けによる JSON の解析や、プログラムからのスキーマ検証が必要な場合は、必ず schemantic を使用してください。
- 抽象クラスに
@Schema()を付与します。 - 抽象スキーマクラスの名前には
$プレフィックスを使用します(例:abstract class $User)。 .g.dartスキーマファイルを生成するには、必ずdart run build_runner buildを実行します。
基本的な使い方
- スキーマを定義する:
import 'package:schemantic/schemantic.dart';
part 'my_file.g.dart'; // Must match the filename
@Schema()
abstract class $MyObj {
String get name;
$MySubObj get subObj;
}
@Schema()
abstract class $MySubObj {
String get foo;
}
- 生成されたクラスを使用する:
ビルダーは、ファクトリーコンストラクター(MyObj.fromJson)と通常のコンストラクターを持つ具象クラス MyObj($ なし)を作成します。
// Creating an instance
final obj = MyObj(name: 'test', subObj: MySubObj(foo: 'bar'));
// Serializing to JSON
print(obj.toJson());
// Parsing from JSON
final parsed = MyObj.fromJson({'name': 'test', 'subObj': {'foo': 'bar'}});
- 実行時にスキーマにアクセスする:
生成されたデータクラスには、SchemanticType<T> 型の静的フィールド $schema があります。このフィールドを使って、定義を関数に渡したり、JSON スキーマの生データを取り出したりできます。
// Access JSON schema
final schema = MyObj.$schema.jsonSchema;
print(schema.toJson());
// Validate arbitrary JSON at runtime
final validationErrors = await schema.validate({'invalid': 'data'});
プリミティブスキーマ
完全なデータクラスが必要ない場合、Schemantic ではスキーマを動的に作成する関数を提供しています。
final ageSchema = SchemanticType.integer(description: 'Age in years', minimum: 0);
final nameSchema = SchemanticType.string(minLength: 2);
final nothingSchema = SchemanticType.voidSchema();
final anySchema = SchemanticType.dynamicSchema();
final userSchema = SchemanticType.map(.string(), .integer()); // Map<String, int>
final tagsSchema = SchemanticType.list(.string()); // List<String>
ユニオン型(AnyOf)
フィールドで複数の型を受け入れるには、@AnyOf を使用します。
@Schema()
abstract class $Poly {
@AnyOf([int, String, $MyObj])
Object? get id;
}
Schemantic は、値を処理するための専用ヘルパークラス(例:PolyId)を生成します。
final poly1 = Poly(id: PolyId.int(123));
final poly2 = Poly(id: PolyId.string('abc'));
フィールドアノテーション
より細かな検証の境界を設定するために、専用のアノテーションを使用できます。
@Schema()
abstract class $User {
@IntegerField(
name: 'years_old', // Change JSON key
description: 'Age of the user',
minimum: 0,
defaultValue: 18,
)
int? get age;
@StringField(
minLength: 2,
enumValues: ['user', 'admin'],
)
String get role;
}
再帰スキーマ
ツリーのような再帰構造では、生成される jsonSchema プロパティ内で useRefs: true を使用する必要があります。定義は通常どおり行います。
@Schema()
abstract class $Node {
String get id;
List<$Node>? get children;
}
注:Node.$schema.jsonSchema(useRefs: true) は、JSON Schema $ref を含むスキーマを生成します。