shelf_rest 0.1.4 copy "shelf_rest: ^0.1.4" to clipboard
shelf_rest: ^0.1.4 copied to clipboard

outdatedDart 1 only

Shelf components that makes it easy to create uniform, hierarchical REST resources.

REST Handler for Dart Shelf #

Build Status

Introduction #

Provides Shelf components that makes it easy to create uniform, hierarchical REST resources.

Usage #

In Shelf REST each REST resource is represented by a class containing methods that correspond to the REST http methods.

REST resources are typically hierarchical and this is modeled in Shelf REST as child resources.

Shelf REST uses shelf_bind to create handlers from the methods of the resource class and shelf_route to create routes for them.

For example a RESTful resource for a bank account might have the following types of operations

Search Accounts

GET /accounts?name='Freddy'

Fetch a single Account

GET /accounts/1234

Create an Account

POST /accounts

Update an Account

PUT /accounts/1234

Delete an Account

DELETE /accounts/1234

This is the standard pattern in Shelf REST and can be implemented as follows


@RestResource('accountId')
class AccountResource {
  List<Account> search(String name) => .....;

  Account create(Account account) => .....;

  Account update(Account account) => .....;

  Account find(String accountId) => ...;

  void delete(String accountId) => ...;
}

The @RestResource('accountId') annotation tells Shelf REST to use accountId as the path variable. The route for DELETE would look like

DELETE /accounts/{accountId}

You can then create the routes for this resource using the restRouter function

var router = restRouter('/accounts', new AccountResource());

Shelf REST follows a standard naming convention to minimise configuration. This also serves to promote consistency in how you name your methods.

You can however override the default naming with annotations

@ResourceMethod(operation: RestOperation.FIND)
Account fetchAccount(String accountId) => ...;

Hierarchical Resources #

It is common to create hierarchical REST resources.

For example, we might want to allow deposits to be made to our account as follows

PUT ->  /accounts/1234/deposits/999

This is referred to in Shelf REST as a child resource. The deposit resource is a child of the account resource.

To create a child resource we add a childResources property to our account resource. This is a map from child path -> resource

@RestResource('accountId')
class AccountResource {

  ....

  Map<dynamic, dynamic> childResources = {
    '/deposits' : new DepositResource()
  };
}

And then create the DepositResource

@RestResource('depositId')
class DepositResource {

  @ResourceMethod(method: 'PUT')
  Deposit create(Deposit deposit) => ...;
}

Note, that the default HTTP method for a create operation is POST. PUT is often used when we know the primary key of the resource when we invoke the create.

In Shelf REST we do that by overriding the HTTP method with the ResourceMethod annotation.

Note the routes for the DepositResource will be created automatically when you create the router for the AccountResource. You only pass the top resource into createRouter (or related functions like createHandler, bindResource). To see this in action simply call Shelf Route's printRoutes function

printRoutes(router);

You can see that the following routes were created

GET    ->  /accounts{?name}                            => bound to search method
POST   ->  /accounts                                   => bound to create method
GET    ->  /accounts/{accountId}                       => bound to find method
PUT    ->  /accounts/{accountId}                       => bound to update method
DELETE ->  /accounts/{accountId}                       => bound to delete method
PUT    ->  /accounts/{accountId}/deposits/{depositId}  => bound to create method of DepositResource

Note that any arguments that are not existing path variables will be added to the query of the uri template. So

List<Account> search(String name) => .....;

produces

GET    ->  /accounts{?name}

Middleware #

You can add middleware that will be included in the route created for a resource method using the ResourceMethod annotation.

@ResourceMethod(middleware: logRequests)
Account find(String accountId) => ...;

In the future middleware will likely be supported in the RestResource annotation and possibly the childResources property

Validation #

As shelf_bind is used to create Shelf handlers from the resource methods, validation of request parameters comes for free (courtesy of constrain).

See the shelf_bind and constrain doco for details.

Validation settings can be set at the bindResource (and related) function and overridden via the ResourceMethod annotation.

var router = restRouter('/accounts', new AccountResource(),
    validateParameters: false);
@ResourceMethod(validateParameters: true)
Account find(String accountId) => ...;

Conventions #

Shelf REST uses the following conventions by default. Each can be overriden with annotations.

  • create ... POST

TODO: more doco

0
likes
0
pub points
8%
popularity

Publisher

unverified uploader

Shelf components that makes it easy to create uniform, hierarchical REST resources.

Homepage

License

unknown (LICENSE)

Dependencies

constrain, option, shelf, shelf_bind, shelf_exception_response, shelf_path, shelf_route

More

Packages that depend on shelf_rest