soti_schema_plus 1.3.0
soti_schema_plus: ^1.3.0 copied to clipboard
A tool for generating schemas from Dart data classes.
soti_schema_plus #
soti_schema_plus is a fork of https://github.com/shtse8/SotiSchema, which
appears to be abandoned. It provides for generating JSON schemas directly from
your Dart data classes, whether you're working with freezed or
json_serializable.
This package automatically generates JSON Schema (draft 2020-12) from your Dart classes, making it easy to maintain consistent schemas alongside your data models.
🚀 Getting Started #
Installation #
Add these dependencies to your pubspec.yaml:
dependencies:
soti_schema_plus: ^1.3.0
freezed_annotation: ^3.1.0 # if using freezed
json_annotation: ^4.9.0 # if using json_serializable
dev_dependencies:
build_runner: ^2.4.13
freezed: ^3.2.0 # if using freezed
json_serializable: ^6.11.0 # if using json_serializable
Configuration #
Configure your build.yaml file at the root of your project (this registers the
builder so dependents like your app/example can use it):
builders:
soti_schema:
import: "package:soti_schema_plus/builder.dart"
builder_factories: ["sotiSchemaBuilder"]
build_extensions: {".dart": [".g.part"]}
auto_apply: dependents
build_to: cache
applies_builders: ["source_gen|combining_builder"]
For projects using both freezed and json_serializable, add this to your
build.yaml:
targets:
$default:
builders:
json_serializable:
options:
explicit_to_json: true
explicit_to_json: trueensures that nested objects are correctly serialized by generating explicittoJsonmethods.
Run Code Generation #
Generate the schema files using build_runner:
dart run build_runner build --delete-conflicting-outputs
💡 How to Use SotiSchema #
Example with freezed #
Here's how to generate a JSON schema using SotiSchema with a freezed class:
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:soti_schema_plus/annotations.dart';
part 'example_model.freezed.dart';
part 'example_model.g.dart';
@freezed
@SotiSchema()
class ExampleModel with _$ExampleModel {
const ExampleModel._(); // Required for custom getters
const factory ExampleModel({
@Default('') String name,
@Default(0) int age,
@Default([]) List<String> hobbies,
}) = _ExampleModel;
factory ExampleModel.fromJson(Map<String, dynamic> json) =>
_$ExampleModelFromJson(json);
@jsonSchema
static String get schema => _$ExampleModelSchema;
}
Example with json_serializable #
Prefer json_serializable? SotiSchema has you covered:
import 'package:json_annotation/json_annotation.dart';
import 'package:soti_schema_plus/annotations.dart';
part 'example_model.g.dart';
@SotiSchema()
@JsonSerializable()
class ExampleModel {
final String name;
final int age;
final List<String> hobbies;
ExampleModel({
this.name = '',
this.age = 0,
this.hobbies = const [],
});
factory ExampleModel.fromJson(Map<String, dynamic> json) =>
_$ExampleModelFromJson(json);
Map<String, dynamic> toJson() => _$ExampleModelToJson(this);
@jsonSchema
static String get schema => _$ExampleModelSchema;
@jsonSchema
static Map<String, dynamic> get schemaMap => _$ExampleModelSchemaMap;
}
Adding Descriptions to Your Schema #
When generating schemas with SotiSchema, you can include descriptions for your fields in two ways:
-
Doc Comments: Use regular Dart doc comments (
///) above your class fields. SotiSchema will automatically extract these comments and include them as descriptions in the generated schema. -
@DescriptionAnnotation: If you prefer more control or want to add descriptions that differ from your doc comments, you can use the@Descriptionannotation. This approach allows you to provide explicit descriptions directly.
Example with Doc Comments
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:soti_schema_plus/annotations.dart';
part 'example_model.freezed.dart';
part 'example_model.g.dart';
@freezed
@SotiSchema()
class ExampleModel with _$ExampleModel {
const ExampleModel._();
const factory ExampleModel({
/// The name of the person.
@Default('') String name,
/// The age of the person in years.
@Default(0) int age,
/// A list of hobbies the person enjoys.
@Default([]) List<String> hobbies,
}) = _ExampleModel;
factory ExampleModel.fromJson(Map<String, dynamic> json) =>
_$ExampleModelFromJson(json);
@jsonSchema
static String get schema => _$ExampleModelSchema;
}
In this example, the doc comments will be used as descriptions in the generated JSON schema.
Example with @Description Annotation
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:soti_schema_plus/annotations.dart';
part 'example_model.freezed.dart';
part 'example_model.g.dart';
@freezed
@SotiSchema()
class ExampleModel with _$ExampleModel {
const ExampleModel._();
const factory ExampleModel({
@Description('The name of the person.')
@Default('') String name,
@Description('The age of the person in years.')
@Default(0) int age,
@Description('A list of hobbies the person enjoys.')
@Default([]) List<String> hobbies,
}) = _ExampleModel;
factory ExampleModel.fromJson(Map<String, dynamic> json) =>
_$ExampleModelFromJson(json);
@jsonSchema
static String get schema => _$ExampleModelSchema;
}
In this example, the @Description annotations will be used as descriptions in
the generated JSON schema.
Flexible Schema Naming #
With SotiSchema, you have the freedom to name your schema methods however you
like and choose between returning a String or Map<String, dynamic>.
SotiSchema adapts to your needs:
@jsonSchema
static String get customSchemaName => _$ExampleModelSchema;
@jsonSchema
static Map<String, dynamic> get anotherSchema => _$ExampleModelSchemaMap;
🎯 Complete Example #
See the example/ directory for a complete working example that demonstrates:
- Basic freezed models with schema generation
- JsonSerializable models with dual schema formats (String and Map)
- Models with documentation comments
- Complex nested objects with schema references
- Various data types including DateTime, Maps, and Lists
Run the example:
cd example
dart pub get
dart run build_runner build --delete-conflicting-outputs
dart run main.dart
📝 Generated Schema Format #
SotiSchema generates JSON Schema draft 2020-12 compatible schemas. Here's an example of what gets generated:
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "The name of the person.",
"default": ""
},
"age": {
"type": "integer",
"description": "The age of the person in years.",
"default": 0
},
"hobbies": {
"type": "array",
"items": {
"type": "string"
},
"description": "A list of hobbies the person enjoys.",
"default": []
}
},
"$defs": {}
}
🤝 Contributing #
Contributions are welcome! Please feel free to submit a Pull Request.
📄 License #
This project is licensed under the MIT License - see the LICENSE file for details.