Skip to content

Reactors

Reactors are stateless collections of methods that can perform actions inside Hantera based on input. Reactors can be used to create custom APIs and automate background work.

A Reactors starts with a Component that is then configured as a Reactor instance. This makes Reactor components re-usable for many different use-cases.

Reactors can be scheduled in Jobs or invoked directly through it’s public API, turning them into custom API endpoints to your Hantera installation.

Reactors methods can take arguments, and return values. Given the nature of Reactors, besides being a bridge between Hantera’s Actors and the outside world, they can often replace serverless functions provided by many of today’s cloud providers.

A Simple Example

To get a better idea of what a Reactor looks like, take a look at the below Reactor Component:

order.hreactor
export create(args) =>
let deliveryId = newid
let channel = registry->$'channels/{args.channelKey}'
let orderCommands = [{
type = 'setChannelKey'
value = args.channelKey
},{
type = 'createDelivery'
deliveryId = deliveryId
}]
let orderLineCommands =
args.items
select i => {
type = 'createOrderLine'
deliveryId = deliveryId
productNumber = i.productNumber
quantity = i.quantity
}
from channel match
nothing |> 'Channel not found'
{ currencyCode: not nothing, taxIncluded: bool } |> messageActor(
'order'
'new'
[{
type = 'create'
body = {
currencyCode = channel.currencyCode
taxIncluded = channel.taxIncluded
commands = [orderCommands, orderLineCommands] flatten
}
}]
)
|> 'Something went wrong'

This reactor provides a creates a simple API to create orders based on channel settings. The export statement creates a public method that we can call.

Testing the Reactor

In order to test this reactor, we must first install the component in Hantera. For the sake of this guide, we will use a manifest file and push the component to Hantera using hantera-cli. We will then create the Reactor instance itself using another manifest file referencing the newly created component. By instantiating the reactor we make it possible to call it or schedule it using a Job.

  1. Start by creating the manifest file for Reactor component:

    h_manifest.yaml
    uri: /resources/components/order.hreactor
    spec:
    codeFile: order.hreactor
  2. Next, let’s add the manifest that will instantiate the Reactor resource to the above file:

    h_manifest.yaml
    ---
    uri: /resources/reactors/order
    spec:
    componentId: order.hreactor
  3. To allow us to test, we should also define a channel so the reactor can actually create an order:

    h_manifest.yaml
    ---
    uri: /resources/registry/channels/WEB_SE
    spec:
    value:
    currencyCode: 'SEK'
    taxIncluded: true
  4. Now let’s apply the manifests to our Hantera instance:

    Terminal window
    h_ manage apply h_manifest.yaml
  5. You should now have a new Reactor resource live in your Hantera. You can verify it by querying the Reactors API. This should return metadata about the Reactor and it’s available methods:

    GET https://<hantera-hostname>/resources/reactors/order
    Authorization: Bearer <YOUR TOKEN>
  6. Once you have verified that the Reactor is there, you can now call the method using the API:

    POST https://<hantera-hostname>/resources/reactors/order/create
    Authorization: Bearer <YOUR TOKEN>
    Content-Type: application/json
    {
    "channelKey": "WEB_SE",
    "items": [{
    "sku": "prod1",
    "quantity": 1
    }]
    }

That’s it. Notice how the method name defined in the Reactor component code is manifested in it’s public API, while we can name the Reactor anything we want in the actual Reactor resource.

To see the complete example, visit the Cookbook.

Access Control

You may wonder, how is it safe to make arbitrary external requests available through the public API. This sounds like a recipe for all kinds of denial-of-service problems.

While it’s true that Reactors are powerful and used wrong it can be misused. Reactors are tightly integrated with Hantera’s access control layer, which means that calling Reactor Methods require explicit permission for the session. Additinally, as opposed to many other similar platforms, Hantera makes all effects of Reactors very easy to monitor through the Reactor Logs.

The ACE pattern for reactors looks like this:

reactor[/<id>][/<method>]:read|write|invoke