Ming.Router behaviour (Ming v0.1.0)

View Source

Command routing macro to allow configuration of each command to its command handler.

Example

Define a router module which uses Ming.Router and configures available request to dispatch:

defmodule BankRouter do
  use Ming.Router


  dispatch OpenAccount,
    to: OpenAccountHandler,
end

The to option determines which module receives the request being dispatched.

This command handler module must implement a handle/1 function. It receives the command to execute.

Once configured, you can either dispatch a request by using the module and

specifying the application:

command = %OpenAccount{account_number: "ACC123", initial_balance: 1_000}

:ok = BankRouter.send(command, application: BankApp)

Or, more simply, you should include the router module in your application:

defmodule CommandProcssor do
  use Ming.CommandProcssor , otp_app: :my_app

  router MyApp.Router
end

Then dispatch commands using the app:

command = %OpenAccount{account_number: "ACC123", initial_balance: 1_000}

:ok = BankApp.send(command)

Alternatively, you may specify the name of a function on your handle module to which the command will be dispatched:

Example

defmodule BankRouter do
  use Commanded.Commands.Router


  # Will route to `BankAccount.open_account/2`
  dispatch OpenAccount, to: BankAccount, function: :open_account 
end

Metadata

You can associate metadata with all events created by the command.

Supply a map containing key/value pairs comprising the metadata:

:ok = BankApp.send(command, metadata: %{"ip_address" => "127.0.0.1"})

Summary

Callbacks

Dispatch the given event to all registered handler.

Dispatch the given command to all registered handler.

Dispatch the given command to one registered handler.

Dispatch the given command to one registered handler.

Functions

Configure the command, or list of commands, to be dispatched to the corresponding handler.

Include the given middleware module to be called before and after success or failure of each command dispatch(send/publish/post)

Include the given middleware module to be called before and after success or failure of each message dispatch using post

Include the given middleware module to be called before and after success or failure of each message dispatch using publish

Include the given middleware module to be called before and after success or failure of each message dispatch using send

Types

publish_resp()

@type publish_resp() :: :ok | {:error, term()} | {:error, [term()]}

send_resp()

@type send_resp() ::
  :ok
  | {:ok, any()}
  | {:error, :unregistered_command}
  | {:error, :more_than_one_handler_founded}
  | {:error, term()}

Callbacks

publish(event)

@callback publish(event :: struct()) :: publish_resp()

Dispatch the given event to all registered handler.

Returns :ok or {:ok, any()} on success, or {:error, reason} on failure.

Example

event = %AccountOpened{account_number: "ACC123", initial_balance: 1_000}
:ok = BankRouter.publish(event)

publish(command, timeout_or_opts)

@callback publish(
  command :: struct(),
  timeout_or_opts :: non_neg_integer() | :infinity | Keyword.t()
) :: publish_resp()

Dispatch the given command to all registered handler.

  • command is a command struct which must be registered with the router.

  • timeout_or_opts is either an integer timeout, :infinity, or a keyword list of options.

    The timeout must be an integer greater than zero which specifies how many milliseconds to allow the command to be handled, or the atom :infinity to wait indefinitely. The default timeout value is five seconds.

    Alternatively, an options keyword list can be provided with the following options.

    Options:

    • request_uuid - an optional UUID used to identify the command being dispatched.

    • correlation_id - an optional UUID used to correlate related commands/events together.

    • metadata - an optional map containing key/value pairs comprising the metadata to be associated with all events created by the command.

    • timeout - as described above.

    • concurrency_timeout - the maximum amount of time (in milliseconds or :infinity) each task is allowed to execute for. Defaults to 30_000

    • max_concurrency - sets the maximum number of tasks to run at the same time. Defaults toSystem.schedulers_online/0.

Returns :ok on success, or {:error, reason} on failure.

Example

command = %OpenAccount{account_number: "ACC123", initial_balance: 1_000}

:ok = BankRouter.send(command, consistency: :strong, timeout: 30_000)

send(command)

@callback send(command :: struct()) :: send_resp()

Dispatch the given command to one registered handler.

Returns :ok on success, or {:error, reason} on failure.

Example

command = %OpenAccount{account_number: "ACC123", initial_balance: 1_000}
:ok = BankRouter.send(command)

send(command, timeout_or_opts)

@callback send(
  command :: struct(),
  timeout_or_opts :: non_neg_integer() | :infinity | Keyword.t()
) :: send_resp()

Dispatch the given command to one registered handler.

  • command is a command struct which must be registered with the router.

  • timeout_or_opts is either an integer timeout, :infinity, or a keyword list of options.

    The timeout must be an integer greater than zero which specifies how many milliseconds to allow the command to be handled, or the atom :infinity to wait indefinitely. The default timeout value is five seconds.

    Alternatively, an options keyword list can be provided with the following options.

    Options:

    • request_uuid - an optional UUID used to identify the command being dispatched.

    • correlation_id - an optional UUID used to correlate related commands/events together.

    • metadata - an optional map containing key/value pairs comprising the metadata to be associated with all events created by the command.

    • timeout - as described above.

Returns :ok on success, or {:error, reason} on failure.

Example

command = %OpenAccount{account_number: "ACC123", initial_balance: 1_000}

:ok = BankRouter.send(command, consistency: :strong, timeout: 30_000)

Functions

dispatch(request_module_or_modules, opts)

(macro)

Configure the command, or list of commands, to be dispatched to the corresponding handler.

Example

defmodule BankRouter do
  use Commanded.Commands.Router

  dispatch [OpenAccount, DepositMoney], to: BankAccount
end

middleware(middleware_module)

(macro)

Include the given middleware module to be called before and after success or failure of each command dispatch(send/publish/post)

The middleware module must implement the Ming.Middleware behaviour.

Middleware modules are executed in the order they are defined.

Example

defmodule BankRouter do
  use Ming.Router

  middleware CommandLogger
  middleware MyCommandValidator
  middleware AuthorizeCommand

  dispatch [OpenAccount, DepositMoney], to: BankAccount
end

post_middleware(middleware_module)

(macro)

Include the given middleware module to be called before and after success or failure of each message dispatch using post

The middleware module must implement the Ming.Middleware behaviour.

Middleware modules are executed in the order they are defined.

Example

defmodule BankRouter do
  use Ming.Router

  post_middleware CommandLogger
  post_middleware MyCommandValidator
  post_middleware AuthorizeCommand

  dispatch [OpenAccount, DepositMoney], to: BankAccount
end

publish_middleware(middleware_module)

(macro)

Include the given middleware module to be called before and after success or failure of each message dispatch using publish

The middleware module must implement the Ming.Middleware behaviour.

Middleware modules are executed in the order they are defined.

Example

defmodule BankRouter do
  use Ming.Router

  publish_middleware CommandLogger
  publish_middleware MyCommandValidator
  publish_middleware AuthorizeCommand

  dispatch [OpenAccount, DepositMoney], to: BankAccount
end

send_middleware(middleware_module)

(macro)

Include the given middleware module to be called before and after success or failure of each message dispatch using send

The middleware module must implement the Ming.Middleware behaviour.

Middleware modules are executed in the order they are defined.

Example

defmodule BankRouter do
  use Ming.Router

  send_middleware CommandLogger
  send_middleware MyCommandValidator
  send_middleware AuthorizeCommand

  dispatch [OpenAccount, DepositMoney], to: BankAccount
end