Skip to main content

Controllers

Introduction

Controller groups a set of handlers, that are meant to receive messages, and return responses to them. By using decorators, we describe a route that points to a handler, which is free to perform any task we want to, and optionally return a result, that will be sent to the client.

Routing

By use of MessagePattern() decorator we can create a route, that will the handle specific message.

ping.controller.ts
import { Controller, MessagePattern } from 'electron-broker';

@Controller()
export default class PingPongController {
@MessagePattern('ping')
public getPong(): string {
return 'pong';
}
}

Optionally you can provide a pattern to Controller() decorator, and prefix each route with it.

shop.controller.ts
import { Controller, MessagePattern } from 'electron-broker';

@Controller('shop')
export default class ShopController {
@MessagePattern('get-products')
public getProducts(): string[] {
return ['bread', 'rice', 'noodles'];
}
}

The broker will perform concatenation with - symbol on both patterns. Therefore, this route will be accessible on shop-get-products pattern.

Registration

Broker class exposes the controllers property in its configuration, that's where you'll have to provide references to your controllers, to register them within the broker context.

/src/renderer/index.tsx
import 'reflect-metadata';
import { Broker, BrokerClient, BrokerFactory } from 'electron-broker';
import ShopController from './shop.controller.ts';

let broker: Broker;

async function createBroker() {
broker = await BrokerFactory.createRendererBroker({
controllers: [new ShopController()],
secure: true,
});

broker.start();
}
note

It's also possible to register your controllers with built-in support of dependency injection, see Dependency Injection section for more information.

Message structure

Each message sent by the Broker is wrapped into BrokerEvent object, which contains all information required to correctly forward them. Let's have a look at its structure:

PropertyDescription
typeREQUEST or RESPONSE
eventIdUnique identifier of the message
patternMessage pattern
dataPayload of the message

Data

Accessing the data property of BrokerEvent interface is done through use of a @Data() decorator.

shop.controller.ts
import { Controller, MessagePattern, Data } from 'electron-broker';

interface Product {
name: string;
price: number;
}

@Controller('shop')
export default class ShopController {
@MessagePattern('add-product')
public addProduct(@Data() data: Product): Promise<string> {
return `Created product with name ${data.name}`;
}
}

EventId

It's also also possible to access eventId property with @EventId() decorator.

event-id.controller.ts
import { Controller, MessagePattern, EventId } from 'electron-broker';

@Controller()
export default class EventIdController {
@MessagePattern('display-event-id')
public addProduct(@EventId() eventId: string): void {
return `This message id is: ${eventId}`;
}
}

Custom decorators

Custom decorators allow you to access any property of BrokerEvent object. This becomes useful, when you decide to inject a custom property, with your own middleware.

type.decorator.ts
import { createParamDecorator } from 'electron-broker';

const Type = createParamDecorator((options, brokerEvent) => {
return brokerEvent.type;
});

export default Type;