shelf_bind 0.2.1 copy "shelf_bind: ^0.2.1" to clipboard
shelf_bind: ^0.2.1 copied to clipboard

outdatedDart 1 only

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 via Constructor

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 via Properties

If you prefer, you can bind via properties (fields or setters) instead of via the constructor.

To do that you specify the bindMode named argument as BindMode.PROPERTY (default is BindMode.CONSTRUCTOR) like

final routeHandler = route.router()
      ..get('/person/{name}', bind.bind(Person, {'name': #firstname}, _handlePerson,
      		bindMode: BindMode.PROPERTY))
      .handler

plus you must have a default (unnamed) constructor that takes no mandatory arguments. For example a constructor like

class Person {
  String name;
  
  Person();
}

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 #

See open issues.

Contributing #

If you want to contribute, please:

  1. fork the repo and implement your changes with good unit test coverage of your changes
  2. create a pull request
  3. create an issue detailing the change and link the PR to it
0
likes
0
pub points
20%
popularity

Publisher

unverified uploader

A binding handler for shelf

Homepage

License

unknown (LICENSE)

Dependencies

shelf, shelf_route

More

Packages that depend on shelf_bind