shelf_bind 0.1.0 shelf_bind: ^0.1.0 copied to clipboard
A binding handler for shelf
Binding Handler for Dart Shelf #
Introduction #
Provides Shelf middleware for binding Shelf request and response data to class properties.
Shelf Bind currently supports the following bindings:
- Binding to Shelf Route path variables
- Binding request Json Body
No response bindings yet.
Using #
Binding to Shelf Route Path Variables #
Binding a simple path variable
final routeHandler = route.router()
..get('/person/{name}', bind.bind(Person, {'name': #firstname}, _handlePerson))
.handler
This binds the path variable called name as defined in the path /person/{name} to the named argument called firstname of the Person.build constructor and calling the _handlePerson function when matched.
The constructor looks like
Person.build({String firstname}) : this(firstname);
The handlers for Shelf Bind differ from the standard Shelf handlers by an extra argument which is the bound object.
_handlePerson(Person person, shelf.Request request)
Note build is the default name for the constructor. It can be overriden by passing the constructor parameter to bind
final routeHandler = route.router()
..get('/person/{name}', bind.bind(Person, {'name': #firstname}, _handlePerson,
constructor: #foo))
.handler
Would look for a constructor Person.foo({String firstname})
.
Query Params
To bind to a query parameter
final routeHandler = route.router()
..get('/person{?name}', bind.bind(Person, {'name': #firstname}, _handlePerson))
.handler
The only change was that path passed to get is now '/person{?name}'
Binding to a Json Body #
Binding to a Json body is very similar. Instead you call the bindJsonBody function.
final routeHandler = route.router()
..post('/person', bind.bindJsonBody(Person, _handlePerson)))
.handler
As this is binding to a Json map it does not take the binding map as above.
Example #
Full source at example/binding_example.dart
The domain objects
class Person {
final String name;
Person(this.name);
Person.build({String name}) : this(name);
Person.fromJson(Map json) : this(json['name']);
Map toJson() => { 'name': name };
String toString() => 'Person[name: $name]';
}
A simple handler that just echos back the bound person
shelf.Response _handlePerson(Person person, shelf.Request request) {
print(person);
return new shelf.Response.ok('${request.method} ${request.requestedUri} '
'=> ${person.toJson()}\n');
}
The routes and bindings
final pathBindHandler = bind.bind(Person, {'name': #name}, _handlePerson);
var router = (route.router()
..get('/person/{name}', pathBindHandler)
..get('/person{?name}', pathBindHandler)
..post('/person', bind.bindJsonBody(Person, _handlePerson)))
.handler;
var handler = const shelf.Stack()
.addMiddleware(shelf.logRequests())
.addHandler(router);
Serve it up
io.serve(handler, 'localhost', 8080).then((server) {
print('Serving at http://${server.address.host}:${server.port}');
});
}
Try it out
First route
curl http://localhost:8080/person/fred
The output should look like
GET http://localhost:8080/person/fred => {name: fred}
Second route
curl http://localhost:8080/person?name=fred
Third route (json POST)
curl -d '{"name": "fred"}' http://localhost:8080/person
TODO #
- Some real tests ;-)
- Link to constraints lib
- Response binding