Repository navigation
rok-sqlc 0.3.0
Validated bodies and HTTP extractors (ADR 0015). A run without the new
validate derive and extractors key generates byte-for-byte what 0.2.1
generates.
Added
-
derive = ["serde", "validate"](-d validate,Derive::Validate) adds
validator::Validate(validator 0.21) to every create input and update
patch, with rules taken from the schema and English messages naming the
column ("name must be at most 80 characters"):VARCHAR(n),CHARACTER VARYING(n),CHAR(n)andCHARACTER(n)give
length(max = n), counted in characters;- a single-column
CHECKcomparingchar_length(col),
character_length(col)orlength(col)with an integer gives a
lengthbound, combined with the declared length (the tighter bounds
win, andequalwhen they meet); - a single-column
CHECKcomparing an integer or float column with a
literal (>=,>,<=,<, either side),BETWEEN, or anANDof
these givesrange. A strict bound on an integer becomes inclusive
(> 0ismin = 1); on a float it stays strict (exclusive_min), and
one that can't be represented exactly is dropped; - on a
NUMERICcolumn the range is acustomrule calling a generated
<field>_in_rangefunction, with the coderangeandrange's
min/maxparams, since validator'srangecan't compareDecimal; - a typed id over text implements
validator::ValidateLength<u64>, and a
typed id over an integervalidator::ValidateRange, so a column's
lengthorrangerule applies through the id and through foreign keys
using it. A typed id overNUMERICgets no range rule.
Patch fields are checked only when present. Other
CHECKs,NOT NULL,
enums and value lists are not rules.db/mod.rsnames thevalidator
dependency.validatewithoutserdefails the run. -
extractors = ["axum", "actix_web"](the JSON payload'sextractors, the
repeatable-e/--extractor <axum|actix_web>flag, and
Config::extractorswith the new#[non_exhaustive]Extractor, part of
the stable library API) generatesdb/http/, which needsvalidate:db::http::axum::ValidatedJson<T>(axum 0.8) and
db::http::actix_web::ValidatedJson<T>(actix-web 4), extractors for
anyT: DeserializeOwned + Validate: a generated input or patch, or a
hand-written request type. Each reads the body through its framework's
own JSON extractor (axum::Json<T>,web::Json<T>), so axum's
DefaultBodyLimitand actix-web'sJsonConfig(limit and
Content-Typepredicate) apply; both limits default to 2 MiB;BodyRejection, answered in the Rok error envelope
{"success": false, "error": {"message", "code", "details"?}}:400
MALFORMED_BODYfor a missing or wrongContent-Type, bad JSON syntax,
or a body that can't be read;413PAYLOAD_TOO_LARGEfor a body over
the framework's size limit, with the message
"the request body is over the size limit"from both;422
VALIDATION_FAILEDwith serde's message and nodetailsfor JSON that
doesn't fit the type;422VALIDATION_FAILEDwith validator's errors
asdetailsfor a broken rule. Each framework's rejection is classified
in its module, with the message taken from serde's own error (never the
framework's text), so both answer the same body with the same status,
code and message;ErrorBody,ErrorPayload, the three codes,
BodyRejection::from_serde, andvalidated(body), which checks a
deserialized body against its rules.
With actix-web, no
JsonConfigerror handler is needed.db/mod.rsnames
theaxum,serde_path_to_error(whose error wraps serde's inside axum's
rejection),actix-webandserde_jsondependencies.extractorswithout
validatefails the run, and an unknown framework lists the valid ones.
Withextractors,httpis a reserved module name: a table whose module
would behttpfails with an error that says so (rename it with
[modules]). Withoutextractors, such a table generates as before. -
The schema model keeps each text column's declared length and the simple
CHECKbounds above, throughCREATE TABLE,ADD COLUMN,ALTER COLUMN … TYPE(which replaces or clears them),ADD CONSTRAINT, and renames. -
The README has a "Validated bodies and HTTP extractors" section, from the
new example cratedocs/examples/validated-api.