10 minutesCore RydanticNo external services
1. Create a project
Cargo.toml
2. Define the boundary
TheSignup struct in the complete source below is the contract. #[derive(Model)] supplies parsing, serialization and schema generation.
Coercion is explicit. Removing
coerce makes the string "36" fail integer parsing; the JSON number 36 still works.
3. Copy the complete program
Put this source insrc/main.rs. The same program lives at crates/rydantic/examples/data_contract.rs in the repository.
crates/rydantic/examples/data_contract.rs
4. Run both paths
loc or pointer() to associate it with a form field. code is the machine-readable category; message is a human-readable explanation. errors.to_json() exposes the structured errors for an application response.
5. Share the schema
Signup::json_schema(SchemaMode::Input) describes accepted input, including local-rule annotations for transformations. SchemaMode::Output describes the normalized serialized value. Both are JSON values that can be saved or passed to API tooling.
Keep parsing at the application boundary: the generated schema describes structure, while the model runs trimming, coercion and its other runtime rules. See JSON Schema for portability details.
Try a change
Add"tags":["rust","api"] to the accepted input. Then change the minimum age to 21 and submit age 20. Compare the accepted output with the field path and constraint code in the rejected case.
Next: build a CRUD API
Use the same approach at an HTTP and database boundary.
More model examples
Explore enums, borrowed values and streaming JSON.