Raku Land

Hematite

Hematite

test

Usage

# psgi file use Hematite; my $app = Hematite.new; # middleware $app.use(sub ($ctx, $next) { # some processing... # call next $next($ctx); # some processing... }); class TestMiddleware does Callable { method CALL-ME($ctx, $next) { $next($ctx); } } $app.use(TestMiddleware.new); # routes (can define any http method) $app.GET('/', sub ($ctx) { $ctx.render({'route' => '/'}, 'type' => 'json'); }); #$app.POST('/', sub ($ctx) { $ctx.render({'route' => '/'}, 'type' => 'json'); }); #$app.METHOD('get', '/', sub ($ctx) { $ctx.render({'route' => '/'}, 'type' => 'json'); }); # route with middleware $app.GET( '/with-middleware', [sub ($ctx, $next) { say 'route middleware'; $next($ctx); }], sub ($ctx) { $ctx.render({'route' => '/with-middleware'}, 'type' => 'json'); } ); # route with placeholders/captures $app.GET( '/captures/:c1', sub { say({ 'captures' => $ctx.captures, 'named-captures' => $ctx.named-captures }); } ); # route rendering json $app.GET( '/json', sub ($ctx) { $ctx.render-json( {'hello' => 'world'}, ); } ); # route rendering template $app.GET( '/template', sub ($ctx) { $ctx.render( 'hello', data => { name => 'world', } ); } ); # route rendering inline template/string $app.GET( '/template-inline', sub ($ctx) { $ctx.render( 'hello {{ name }}', inline => True, data => { name => 'world', } ); } ); # groups my $group = $app.group('/group'); $group.GET('/', sub ($ctx) { $ctx.render({'group' => 1}); }); $app;

start crust

crustup [psgi file]

using a more OO approach

class ExampleMiddleware does Hematite::Middleware { method CALL-ME { say 'example-middleware'; return self.next; } } class ExampleAction does Hematite::Action { method middleware { return [ ExampleMiddleware.create, ]; } method CALL-ME { return self.render('example action', inline => True); } } class App is Hematite::App { method startup { self.use(ExampleMiddleware.create); self.GET('/', ExampleAction.create); self.POST('/', 'ExampleAction'); } }

context helpers

class Middleware does Hematite::Middleware { method CALL-ME { self.add-helper('xpty', sub ($ctx) { # do something... }); self.next; self.remove-helper('xpty'); } } my $app = Hematite::App.new; # register global context helper $app.context-helper('xpto', sub ($ctx) { say 'helper...'; }); # register context helpers, directly in the context $app.use(sub ($ctx, $next) { $ctx.add-helper('xptz', sub ($ctx) { # do something... }); $next($ctx); $ctx.remove-helper('xptz'); }); $app.use(Middleware.create); # just call the helper from the context $app.GET('/', sub ($ctx) { $ctx.xpto; $ctx.xptz; $ctx.xpty; });

websockets

my $app = Hematite::App.new; $app.WS('/websocket', sub ($ctx) { $ctx.on('ready', sub { $ctx.log.info('websocket ready'); for 1..10 -> $idx { $ctx.send('message', "ping {$idx}"); } $ctx.send('close'); }); $ctx.on('message', sub ($text) { $ctx.log.info('received: ' ~ $text); }); $ctx.on('close', sub { $ctx.log.info('websocket closed'); }); }); # OR class WSAction does Hematite::Action { method CALL-ME { self.on('ready', sub { self.log.info('websocket ready'); for 1..10 -> $idx { self.send('message', "ping {$idx}"); } self.send('close'); }); self.on('message', sub ($text) { self.log.info('received: ' ~ $text); }); self.on('close', sub { self.log.info('websocket closed'); }); } } $app.WS('/websocket2', WSAction);

TODO

Contributing

  1. Fork it ( https://github.com/[your-github-name]/raku-hematite/fork )
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create a new Pull Request

Contributors