moonmodel — one field description, many projections (← Pydantic / serde / DAO): JSON Schema, OpenAPI, SQL columns and GraphQL SDL from the same declaration.
let user = @moonmodel.Model::new(
"User",
[
@moonmodel.Field::new("id", Big, check=@moonmodel.Check::new(unique=true)),
@moonmodel.Field::new("name", Text, check=@moonmodel.Check::new(longest=64)),
@moonmodel.Field::new("age", Int, required=false),
@moonmodel.Field::new("home", Ref("Address")),
],
doc="somebody with an account",
)
// JSON Schema 2020-12, an OpenAPI Schema Object, CREATE TABLE, type User { … }
println(@json.of(user).stringify(indent=2))
println(@open.of(user, dialect=OpenApi30).stringify(indent=2))
println(@sql.table(user, dialect=Postgres))
println(@sdl.document([user][:]))moon add moonbitstack/moonmodelimport {
"moonbitstack/moonmodel",
"moonbitstack/moonmodel/json",
}| Package | Writes | Costs you |
|---|---|---|
| moonmodel | the description itself | nothing — no dependencies |
| moonmodel/json | JSON Schema 2020-12 | the root package |
| moonmodel/open | an OpenAPI Schema Object, three dialects | the root package |
| moonmodel/sql | columns and CREATE TABLE, three dialects | the root package |
| moonmodel/sdl | GraphQL SDL | the root package |
| Type | Means |
|---|---|
| Bool Int Big Real Text Bytes Stamp | the scalars; Big is 64-bit, Stamp an instant |
| List(Type) Dict(Type) | a sequence, and a mapping with open keys |
| Ref(String) | another model, by name, so descriptions refer to each other without nesting |
| Nest(Model) | a model written where it stands, for the one with no name of its own |
| Any | anything at all |
| Raw(Json) | a schema written out in full, for what this vocabulary cannot say |
| Field | Means |
|---|---|
| least most | closed bounds |
| over under | open bounds — JSON Schema's exclusiveMinimum and exclusiveMaximum |
| step | multipleOf |
| shortest longest | a string's characters or a list's items |
| pattern format | a regular expression, and a named shape such as email |
| options | the values allowed, if the set is closed — any Json, not only text |
| distinct | one list's items must differ |
| unique | no two records carry the same value — only SQL can state this |
| Cannot carry | |
|---|---|
| JSON Schema | unique, which is about the collection and not the value |
| OpenAPI 2.0 | nullable has no keyword — written as x-nullable, which is what its tooling reads |
| OpenAPI 2.0 / 3.0 | an open bound is a boolean beside the closed one, not a number |
| SQL | Dict, Nest and Ref need their own table; List is a column only in Postgres; Any and Raw have no type; pattern is spelled three different ways |
| GraphQL | Dict, Nest, Any and Raw have no type; no bound of any kind reaches the schema |
Install
Download zipmoonmodel — one field description, many projections (← Pydantic / serde / DAO): JSON Schema, OpenAPI, SQL columns and GraphQL SDL from the same declaration.