Let’s get started, by creating our backend. The easiest way to bootstrap an Angel application is to use the Angel CLI:

$ pub global activate angel_cli

$ angel init explode # Optional: Rename the project from 'angel' to 'explode'

$ cd explode && angel rename explode

Next, head to lib/src/routes/routes.dart , and remove the route that serves a default index page:

// Delete this:

app.get('/', (req, ResponseContext res) => res.render('hello'));

Let’s create two services: Bomb and Explosion . Optionally, you may also create corresponding data model classes.

First is the BombService .

class BombService extends Service {

final List<Bomb> bombs = []; @override

index([params]) async => bombs; index([params]) async => bombs; @override

create(data, [params]) async {

// We're actually going to ignore the input data

// in every case, and just spawn a new bomb.

var bomb = new Bomb(id: bombs.length.toString());

bombs.add(bomb);

return bomb;

}

} create(data, [params]) async {// We're actually going to ignore the input data// in every case, and just spawn a new bomb.var bomb = new Bomb(id: bombs.length.toString());bombs.add(bomb);return bomb;

Next, explosions .

AngelConfigurer configureServer() {

return (Angel app) async {

// The `AnonymousService` class is a shortcut

// you can use to create a service with minimal

// functionality, without creating a whole new

// class.

app.use('/explosions', new AnonymousService(create: (Explosion data, [params]) {

// This service will simply echo whatever we give to it.

//

// We expect `data` to be a Map with a `bombId`.

// Validation will be covered in a later tutorial.

return {'bombId': data.bombId};

})); // Use service hooks to add additional functionality to

// services.

//

// This pattern is preferred, as hooks can be applied to any

// service, regardless of what data store (if any) is being

// used.

var service = app.service('explosions') as HookedService;

service.beforeAll(hooks.disable()); // Disable for all clients

};

}

In real life, bombs set off after a defined period of time elapses. We will mimic this functionality by firing an explosion event 10 seconds after every bomb is spawned. We can do this with a service hook:

AngelConfigurer configureServer() {

return (Angel app) async {

app.use('/bombs', new BombService()); var service = app.service('bombs') as HookedService; service.afterCreated.listen((HookedServiceEvent e) {

// Bombs should explode 10 seconds after creation.

var explosionService = e.service.app.service('explosions');

var bomb = e.result as Bomb; new Future.delayed(new Duration(seconds: 10)).then((_) {

print('KABOOM!');

explosionService.create(new Explosion(bombId: bomb.id));

});

});

};

}

Now, we have two (very simple) services that can interact with each other. We want to notify our clients in real-time whenever these interactions occur; WebSockets are a perfect medium to do so. Install angel_websocket :

dependencies:

angel_websocket: ^1.0.0

Finally, we run the AngelWebSocket plug-in just after mounting our services (it actually doesn’t matter whether you do this before or after). It listens to every HookedService we mount, and broadcasts events to all connected clients.

configureServer(Angel app) async {

Db db = app.container.make(Db); await app.configure(new AngelWebSocket(debug: true));

await app.configure(Bomb.configureServer());

await app.configure(Explosion.configureServer());

await app.configure(User.configureServer(db));

}