One model description for MoonBit, projected to JSON Schema, OpenAPI, SQL and GraphQL.
#model.derive(doc="somebody with an account")
pub struct User {
#model.field(unique=true)
id : Int64
#model.field(longest="64")
name : String
age : Int32?
home : Address
}
#model.derive
pub struct Address {
city : String
}// JSON Schema 2020-12, an OpenAPI Schema Object, CREATE TABLE, type User { … }
println(@json.of(User::describe()).stringify(indent=2))
println(@open.of(User::describe(), dialect=OpenApi30).stringify(indent=2))
println(@sql.table(User::describe(), dialect=Postgres))
println(@sdl.document([User::describe(), Address::describe()][:]))rule(name: "model", command: "moonx moonbitstack/moonmodel/cmd/derive@0.1.1 -C \"$mod_dir\" \"$input\" -o \"$output\"")dev_build(rule: "model", input: "models.mbt", output: "models.g.mbt")
formatter(ignore: [ "models.g.mbt" ])
import { "moonbitstack/moonmodel" }| Annotation | Goes on | Means |
|---|---|---|
| #model.derive | a struct | generate T::describe(); name= and doc= set the model's name and text |
| #model.derive | an enum | a field of this type is text limited to its constructors |
| #model.field | a field | everything below |
| #model.skip | a field | leave it out |
| #model.field key | Means |
|---|---|
| name, doc | the field's name in the model, and its text |
| kind | the type, when the field's own says nothing: bool, int, big, real, text, bytes, stamp, any |
| model | the type is the model of this name |
| required, nullable | override what the type says |
| default | a default, read by the field's type, so "0" on a String is text |
| least, most, over, under, step | numeric bounds, as strings, since an annotation has no numbers |
| shortest, longest | the length of text or a list |
| pattern, format | a text field's shape |
| option | one allowed value, repeated |
| distinct, unique | a list's items differ; no two records share the value |
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, nullable=true),
@moonmodel.Field::new("home", Ref("Address")),
],
doc="somebody with an account",
)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 zipOne model description for MoonBit, projected to JSON Schema, OpenAPI, SQL and GraphQL.