.. | ||
example | ||
lib | ||
test | ||
.gitignore | ||
.travis.yml | ||
analysis_options.yaml | ||
CHANGELOG.md | ||
LICENSE | ||
pubspec.yaml | ||
README.md |
validate
Strongly-typed form handlers and validators for Angel.
Version 3.x
is a major improvement over 2.x
, though it does include breaking changes.
package:angel_validate
allows you to easily sanitize incoming data, and to deserialize
that data into Dart classes (usually using package:angel_serialize
).
Field
The basic unit is the Field
class, which is a type-safe way to read
values from a RequestContext
. Here is a simple example of using a
TextField
instance to read a value from the URL query parameters:
app.get('/hello', (req, res) async {
var nameField = TextField('name');
var name = await nameField.getValue(req, query: true); // String
return 'Hello, $name!';
});
A Field
can also use Matcher
objects from package:matcher
(which you may recognize from
its usage in package:test
):
var positiveNumberField = IntField('pos_num').match([isPositive]);
A MapField
can embed a Form
(forms covered below), and when combined with
Field.deserialize
, can be used to deserialize structured data as a body field:
app.post('/map_field', (req, res) async {
var form = Form(fields: [
MapField('todo', todoForm).deserialize(Todo.fromMap),
]);
var data = await form.validate(req);
print(data['todo'] is Todo);
});
There are several included field types:
TextField
- Standard text input.BoolField
- Checks if a field is present; used for checkboxes.NumField
- Base class that parses input as a number.DoubleField
- Specialization ofNumField
for doubles.IntField
- Specialization ofNumField
for integers.DateTimeField
- Parses an input as an ISO-8601 date.FileField
- Validates a file inreq.uploadedFiles
.ImageField
- Usespackage:image
to decode anUploadedFile
into an image.MapField
- Validates a Map using a Form.UriField
- Parses text input into aUri
object.
Forms
The Form
class lets you combine Field
instances, and decode
request bodies into Map<String, dynamic>
. Unrecognized fields are
stripped out of the body, so a Form
is effectively a whitelist.
var todoForm = Form(fields: [
TextField('text'),
BoolField('is_complete'),
]);
// Validate a request body, and deserialize it immediately.
var todo = await todoForm.deserialize(req, TodoSerializer.fromMap);
// Same as above, but with a Codec<Todo, Map> (i.e. via `angel_serialize`).
var todo = await todoForm.decode(req, todoSerializer);
// Same as above, but returns the plain Map without any deserialization.
var todoMap = await todoForm.validate(req);
// Lower-level functionality, typically not called directly.
// Use it if you want to handle validation errors directly, without
// throwing exceptions.
var result = await todoForm.read(req);
print(result.isSuccess);
print(result.errors.length);
@serializable
class _Todo {
String text;
bool isComplete;
}
Form Rendering
TODO: Docs about this
Bundled Matchers
This library includes some Matcher
s for common validations,
including:
isAlphaDash
: Asserts that aString
is alphanumeric, but also lets it contain dashes or underscores.isAlphaNum
: Asserts that aString
is alphanumeric.isBool
: Asserts that a value either equalstrue
orfalse
.isEmail
: Asserts that aString
complies to the RFC 5322 e-mail standard.isInt
: Asserts that a value is anint
.isNum
: Asserts that a value is anum
.isString
: Asserts that a value is aString
.isNonEmptyString
: Asserts that a value is a non-emptyString
.isUrl
: Asserts that aString
is an HTTPS or HTTP URL.
The remaining functionality is
effectively implemented by the matcher
package.