Integrations
Axon Server perfectly works with Axon Framework applications. With minimal configuration, the Axon Framework applications distribute commands and queries through Axon Server and use It as an event store. Sometimes, you want to integrate applications that do not use the Axon Framework, applications that may not be running in a Java virtual machine. This is where the Axon Server Integration option comes in.
Axon Server Integration supports:
-
Sending commands and queries to any application that supports HTTP(s) or RSocket communication.
-
Subscribing to events from these applications.
-
Sending commands and queries to Axon Framework applications through HTTP(s)
-
Publishing events and snapshots to Axon Server through HTTP(s).
-
Reading events and snapshots for an aggregate from Axon Server through HTTP(s).
Endpoints
You must first define an endpoint to forward commands, queries, and events to your application. This endpoint describes your application’s common properties, such as the base address and protocol to reach it. Once you have defined the endpoint, you can register handlers for commands, queries, and events. The endpoint also contains an option for a health operation, which Axon Server uses to check its availability periodically. When the health check fails, Axon Server will no longer route commands and queries to this application and will no longer push events. Once the health check succeeds again, operations will resume.
Endpoints contain the following properties:
- name
-
a logical name for the application
- context
-
the Axon Server context
- type
-
the communication protocol from Axon Server to the application
- wrapping type
-
describes how messages Axon Server delivers to the application
- content type
-
defines the content type of the payload of messages
- base URL
-
the base address of the application, the format depends on the communication protocol
- health URL
-
address of the health check (relative to the base URL)
- command URL
-
the default address for command handlers (relative to the base URL)
- query URL
-
the default address for query handlers (relative to the base URL)
- event URL
-
the default address for event handlers (relative to the base URL)
- properties
-
key/value pairs that Axon Server adds in the communication (dependent on the communication protocol)
The command, query, and event URL can contain placeholder {name}
which Axon Server will replace with the registered handler’s actual name.
The wrapping type is one of the following values:
-
Raw, Axon Server sends the message payload in the request body; additional information is provided as headers.
-
Wrapped, Axon Server wraps the payload in a JSON message containing additional information.
Benefits of "Raw" wrapping type:
-
Smaller messages for binary payloads
-
Direct access to the payload
Benefits of "Wrapped" wrapping type:
-
Easier access to the message metadata
-
Support for batches of events
Axon Server does not know anything about the encoding of the request and event payloads. It uses the content-type
property of the endpoint to pass the correct content type in the Raw
handlers. It also uses the property to form the Wrapped
message content. If the content-type
is application/json
, it embeds the JSON payload as part of the message.
For application/xml
or text/*
content types it adds the payload as a string in the message. For all other content types it embeds the payload as a base64
encoded string.
Currently, Axon Server supports HTTP(s) and RSocket as communication protocols.
HTTP(s)
The URL for HTTP(s) endpoints is the server’s URL. Axon Server adds the custom properties defined on the endpoint as HTTP headers to each request. It expects the health URL to be a GET method, but all handlers must use POST methods.
If the endpoint uses HTTPS with a self-signed certificate, you must configure Axon Server to trust this certificate. You can add trusted certificates by setting the property axoniq.axonserver.integration.trust-manager-files
in axonserver.properties.
For example:
axoniq.axonserver.integration.trust-manager-files=certificate-1.pem,certificate-2.pem
RSocket
The URL for RSocket endpoints is <hostname>:<port>. The command, query, and event URL represent the routing key in the RSocket message.
Axon Server adds the custom properties defined on the endpoint as metadata on the RSocket connection. Note that the keys for the custom properties must be media types.
For Raw
messages the following additional metadata keys are included:
- axonserver/x-PayloadType
-
The payload type for the
Raw
message. - axonserver/x-PayloadRevision
-
The payload revision for the
Raw
message. - axonserver/x-MessageId
-
A unique identifier for the message.
- axonserver/x-Metadata
-
Optional metadata for the message.
- axonserver/x-Priority
-
Priority of the request (commands and queries only).
- axonserver/x-QueryName
-
The name of the query.
- axonserver/x-CommandName
-
The name of the command.
- axonserver/x-RoutingKey
-
Routing key for the command.
- axonserver/x-EventName
-
The name of the event.
- axonserver/x-DateTime
-
The date/time that the event was created (event only).
- axonserver/x-Index
-
The global index of the event in the event store (event only).
- axonserver/x-AggregateId
-
The aggregate identifier of the event (optional).
- axonserver/x-AggregateType
-
The aggregate type of the event (optional).
- axonserver/x-SequenceNumber
-
The sequence number of the event within the aggregate (optional).
All messages are request/reply messages.
Command handlers
To receive commands in your application, register a command handler at an endpoint. The registration of a command handler contains the following information:
- name
-
the name of the command.
- commandUrl
-
the (relative) address of the handler (can be omitted to use the default as defined on the endpoint) .
- loadFactor
-
relative weight for this handler, if there are multiple handlers for a command, handlers with a higher load factor get a higher percentage of the requests.
Endpoint types
Axon Server can send requests containing commands in two different ways. Each endpoint that registers as a command handler must support one of them.
Raw
Axon Server serializes a single command directly into the request’s body when interacting with Raw
endpoints. It provides all other relevant information in the HTTP headers of the request:
-
Content-Type
-
AxonIQ-MessageId
-
AxonIQ-CommandName
-
AxonIQ-PayloadType
-
AxonIQ-PayloadRevision
-
AxonIQ-Priority
Please refer to the API documentation for detailed information about the HTTP request structure.
Wrapped
When interacting with Wrapped
endpoints, Axon Server generates a JSON message that contains the serialized command and all information related to the command. It then sends that JSON message in the request’s body.
Please refer to the API documentation for detailed information about the HTTP request structure.
Query handlers
Query handlers must explicitly register in Axon Server to receive queries. There are two ways to register a query handler - using Axon Server’s Web interface or through the Axon Server HTTP API.
In both cases, Axon Server needs the following information:
- name
-
the name of the query that this handler can handle
- query URL
-
the (relative) address of the handler (can be omitted to use the default as defined on the endpoint) .
Endpoint types
Axon Server can send requests containing queries in two different ways. Each endpoint that registers as a query handler must support one of them.
Raw
Axon Server serializes a single query directly into the request’s body when interacting with Raw
endpoints. It provides all other relevant information in the HTTP headers of the request:
-
Content-Type
-
AxonIQ-MessageId
-
AxonIQ-QueryName
-
AxonIQ-PayloadType
Please refer to the API documentation for detailed information about the HTTP request structure.
Wrapped
When interacting with Wrapped
endpoints, Axon Server generates a JSON message containing the serialized query and all related information. It then sends that JSON message in the request’s body.
Please refer to the API documentation for detailed information about the HTTP request structure.
Event handlers
Any service available at an accessible HTTP/RSocket address can be an event handler. Axon Server can send events to such services via HTTP/RSocket requests. The service must be able to handle requests containing events.
Event handlers must explicitly register in Axon Server to receive events. There are two ways to register an event handler - using Axon Server’s Web interface or through the Axon Server HTTP API.
In both cases, Axon Server needs the following information:
- name
-
a name for the event handler. This name will be the name of the persistent stream serving the events.
- filter
-
a filter for the events, for instance
payloadType = "com.example.events.Event1"
- sequencing policy
-
describes how events will be distributed across events
- sequencing policy parameters
-
optional parameters for the sequencing policy
- segments
-
number of parallel processing segments
- start position
-
where to start processing events (HEAD for the newest event, TAIL for the oldest event)
- event URL
-
the (relative) address of the handler (can be omitted to use the default as defined on the endpoint) .
- batch size
-
the maximum number of events that Axon Server sends in one request to the handler if the endpoint type is
Wrapped
.
Event handlers are backed by persistent streams. To modify the number of segments, change the number of segments for the related persistent stream.
Endpoint types
Axon Server can send HTTP requests containing events in two different ways. Each endpoint that registers as an event handler must support one of them.
Raw
Axon Server serializes a single event directly into the request’s body when interacting with Raw
endpoints. It provides all other relevant information in the headers of the request:
-
Content-Type
-
AxonIQ-MessageId
-
AxonIQ-EventName
-
AxonIQ-DateTime
-
AxonIQ-Index
-
AxonIQ-AggregateId
-
AxonIQ-AggregateType
-
AxonIQ-SequenceNumber
The Raw
type supports sending any binary payload directly.
Please refer to the API documentation for detailed information about the HTTP request structure.
Wrapped
When interacting with Wrapped
endpoints, Axon Server generates a JSON message that contains a list of events. Each element includes a serialized event and all additional information relevant to the event.
Please refer to the API documentation for detailed information about the HTTP request structure.
Integration configuration
Administrators can configure the following properties for integrations:
- axoniq.axonserver.integration.command-attempts
-
Sending commands to an endpoint is retried command-attempts times. Default value is 1.
- axoniq.axonserver.integration.command-retry-backoff
-
The command-retry-backoff property defines the initial waiting time before retrying in milliseconds. After the first retry the retry time is increased exponentially. Default value is 10 milliseconds.
- axoniq.axonserver.integration.query-attempts
-
Sending queries to an endpoint is retried query-attempts times. Default value is 1.
- axoniq.axonserver.integration.query-retry-backoff
-
The query-retry-backoff property defines the initial waiting time before retrying in milliseconds. After the first retry the retry time is increased exponentially. Default value is 10 milliseconds.
- axoniq.axonserver.integration.event-retry-backoff
-
Publishing events to an endpoint is retried as long as the endpoint is healthy and the event handler is registered. The event-retry-backoff property defines the initial waiting time before retrying in milliseconds. After the first retry the retry time is increased exponentially up to a maximum of 30 seconds. Default value is 10 milliseconds.
- axoniq.axonserver.integration.trust-manager-files
-
Comma separated list of files of trusted certificate authorities.
- axoniq.axonserver.integration.allow-insecure-trust-manager
-
Option to allow all insecure events when connecting to an HTTPS endpoint (default false).
Sending messages
You can send messages to Axon Server via HTTP requests. Axon Server supports four types of messages:
-
Commands
-
Queries
-
Events
-
Snapshots
In general, you can use two forms to send these requests to Axon Server:
-
Raw
where the HTTP content is the actual payload of the message, and all additional information is in the HTTP headers -
Wrapped
, where the HTTP content is a JSON object containing the message together with all the relevant information
For the operations on the requests to send messages, check the Axon Server Integration API.
Sending commands
Any application that can not connect directly to Axon Server can still send commands through Axon Server’s HTTP APIs. This document explains the two ways to do so.
Axon Server routes commands based on a routing key in the request. If multiple handlers exist for the same command, Axon Server sends requests with the same routing key to the same handler. Command handlers often rely on the routing consistency provided by routing keys to cache data between requests. |
The Raw
endpoint
The Raw
endpoint URL path follows the /v2/commands/[commandName]
pattern. The content of the HTTP request is the serialized command. The sender may provide additional information through HTTP headers.
There is one required header:
-
Content-Type
: the serialization type for the context
The following headers are optional:
-
AxonIQ-PayloadType
: defines the type of the payload (if missing, the command name as the payload type) -
AxonIQ-Priority
: priority of the request (default is 0, a higher value means higher priority) -
AxonIQ-RoutingKey
: the key used for routing (auto-generated if missing) The code below represents a sample request to thehttp-raw
endpoint sending anio.axoniq.demo.giftcard.api.IssueCardCommand
.
POST http://axonserver:8024/v2/commands/io.axoniq.demo.giftcard.api.IssueCardCommand?context=context1
Content-Type: application/xml
<io.axoniq.demo.giftcard.api.IssueCardCommand>
<id>sample-card-5</id>
<amount>110</amount>
</io.axoniq.demo.giftcard.api.IssueCardCommand>
Axon Server then delegates the command to a command handler registered in the context1
context.
For more details about the Raw
endpoint, please refer to the Send Command API docs.
Wrapped endpoint
The Wrapped
endpoint URL path follows the /v2commands
pattern. The content of the HTTP request is a JSON message containing all the information for a single command. Below is the above request in Wrapped
form.
POST http://axonserver:8024/v2/commands?contexts=default
Content-Type: application/json
{
"payload": "<io.axoniq.demo.giftcard.api.IssueCardCommand><id>sample-card-5</id><amount>110</amount></io.axoniq.demo.giftcard.api.IssueCardCommand>"
"name": "io.axoniq.demo.giftcard.api.IssueCardCommand"
}
The message may contain additional optional fields like payloadType
, routingKey
, priority
, and metaData
.
The serialization format of the query object must match the serialization the query handler expects. Even though the HTTP payload is JSON, if the query handler expects XML, the payload must be XML. If the handler expects a JSON serialized payload, the request would be:
|
For more details about the Wrapped
endpoint, please refer to the Send Command Message API docs.
Sending queries
Any application that can not connect directly to Axon Server can still send queries to it through Axon Server’s HTTP APIs. This document explains the two ways to do so.
Axon Server’s HTTP query endpoint only supports request-response queries. It’s unable to take care of subscription queries at this moment. |
The Raw
endpoint
The Raw
endpoint URL path follows the /v1/queries/[queryName]?context=[contextName]
pattern. The content of the HTTP request is the serialized query. The sender may provide additional information through HTTP headers.
There is one required header:
-
Content-Type
: the serialization type for the context
The following headers are optional:
-
AxonIQ-PayloadType
: defines the type of the payload (if missing, the command name is the payload type) -
AxonIQ-ResponseType
: the expected response type (required when the handler uses Axon Framework) -
AxonIQ-ResponseCount
: use MULTIPLE to indicate that the query handler can return multiple instances of the response type
The code below represents a sample request to the Raw
endpoint sending an io.axoniq.demo.giftcard.api.FetchCardSummariesQuery
.
POST http://axonserver:8024/v2/queries/io.axoniq.demo.giftcard.api.FetchCardSummariesQuery?contexts=default
Content-Type: application/xml
AxonIQ-ResponseType: io.axoniq.demo.giftcard.api.CardSummary
AxonIQ-ResponseCount: MULTIPLE
<io.axoniq.demo.giftcard.api.FetchCardSummariesQuery>
<offset>0</offset>
<limit>100</limit>
</io.axoniq.demo.giftcard.api.FetchCardSummariesQuery>
Axon Server then delegates the query to a query handler registered in the default
context. When the handler responds with a zero or more io.axoniq.demo.giftcard.api.CardSummary
objects, Axon Server serializes the payload and sends it back in the response payload of the HTTP request.
For more details about the Raw
endpoint, please refer to the Send Query API docs.
The Wrapped
endpoint
The Wrapped
endpoint URL path follows the /v2/queries?context=[contextName]
pattern. The content of the HTTP request is a JSON message containing all the information for a single query. Below is the above request in Wrapped
form.
POST http://axonserver:8024/v2/queries?contexts=default
Content-Type: application/json
{
"payload": "<io.axoniq.demo.giftcard.api.FetchCardSummariesQuery><offset>0</offset><limit>100</limit></io.axoniq.demo.giftcard.api.FetchCardSummariesQuery>"
"name": "io.axoniq.demo.giftcard.api.FetchCardSummariesQuery",
"responseType": "io.axoniq.demo.giftcard.api.CardSummary"
}
The message may contain additional optional fields like payloadType
and metaData
. You can use the payloadType
field to specify the payload type in cases where the query name doesn’t equal the payload type for the query message.
The serialization format of the query object must match the serialization the query handler expects. Even though the HTTP payload is JSON, if the query handler expects XML, the payload must be to XML. If the handler expects a JSON serialized payload, the request would be:
|
For more details about the Wrapped
endpoint, please refer to the Send Query Message API docs.
Sending events
Any application that can not connect directly to Axon Server can still send events to it through Axon Server’s HTTP APIs. This document explains the two ways to do so.
The Raw
endpoint
The Raw
endpoint URL path follows the /v1/events/[eventName]?context=[contextName]
pattern. The content of the HTTP request is the serialized event. The sender may provide additional information through HTTP headers.
There is one required header:
-
Content-Type
: the serialization type for the context
The following headers are optional:
-
AxonIQ-AggregateId
: -
AxonIQ-AggregateType
: -
AxonIQ-SequenceNumber
: -
AxonIQ-DateTime
:
The code below represents a sample request to the Raw
endpoint sending a local.application.client.Event
.
POST http://axonserver:8024/v2/events/local.application.client.Event?context=default
Content-Type: application/json
AxonIQ-AggregateId: 901aa5ce-b281-4788-97f2-2be7f236dde6
AxonIQ-AggregateType: Aggregate
AxonIQ-SequenceNumber: 0
AxonIQ-DateTime: 2022-09-22T21:37:00.000+00:00
{
"id": "901aa5ce-b281-4788-97f2-2be7f236dde6",
"text": "New customer created"
}
Axon Server stores the event in the default
context of the event store as specified in the request’s URL.
For more details about the Raw
endpoint, please refer to the Publish Event API docs.
The Wrapped
endpoint
The Wrapped
endpoint can be used to send multiple events in a single transaction.
The Wrapped
endpoint URL path follows the /v1/events?context=[contextName]
pattern. The content of the HTTP request is a JSON array of messages, each containing all the information for a single event. Below is the above request in Wrapped
form.
POST http://axonserver:8024/v2/events?context=default
Content-Type: application/json
[{
"payload": {
"id": "901aa5ce-b281-4788-97f2-2be7f236dde6",
"text": "New customer created"
},
"name": "local.application.client.Event",
"aggregateId": "901aa5ce-b281-4788-97f2-2be7f236dde6",
"aggregateType": "Aggregate",
"sequenceNumber": 0,
"dateTime": "2022-09-22T21:37:00.000+00:00"
}]
The JSON payload may contain additional optional fields such as metaData
.
For more details about the Wrapped
endpoint, please refer to the Publish Event Message API docs.
Sending snapshots
Any application that can not connect directly to Axon Server can still send snapshots to it through Axon Server’s HTTP APIs. This document explains the two ways to do so.
The Raw
endpoint
The Raw
endpoint URL path follows the /v1/snapshots/[aggregeteId]?context=[contextName]
pattern. The content of the HTTP request is the serialized snapshot. The sender may provide additional information through HTTP headers.
There are three required headers:
-
Content-Type
: the serialization type for the context -
AxonIQ-AggregateType
: -
AxonIQ-SequenceNumber
:
The following headers are optional:
-
AxonIQ-DateTime
:
The sequence number of a snapshot must be less than or equal to the last event stored for the aggregate.
The code below represents a sample request to the Raw
endpoint sending a local.application.client.Snapshot
.
POST http://axonserver:8024/v2/snapshots/my-aggregate-id?context=default
Content-Type: application/json
AxonIQ-AggregateType: Aggregate
AxonIQ-SequenceNumber: 0
AxonIQ-DateTime: 2022-09-22T21:37:00.000+00:00
{
"id": "my-aggregate-id",
"name": "Customer name"
}
Axon Server stores the snapshot in the default
context of the event store as specified in the request’s URL.
For more details about the Raw
endpoint, please refer to the Publish Snapshot API docs.
The Wrapped
endpoint
The Wrapped
endpoint URL path follows the /v1/snapshots?context=[contextName]
pattern. The content of the HTTP request is a JSON message containing all the information for a snapshot. Below is the above request in Wrapped
form.
POST http://axonserver:8024/v2/snapshots?context=default
Content-Type: application/json
[{
"payload": {
"id": "my-aggregate-id",
"name": "Customer name"
},
"name": "local.application.client.Snapshot",
"aggregateId": "my-aggregate-id",
"aggregateType": "Aggregate",
"sequenceNumber": 0,
"dateTime": "2022-09-22T21:37:00.000+00:00"
}]
The JSON payload may contain additional optional fields such as metaData
.
For more details about the Wrapped
endpoint, please refer to the Publish Snapshot Message API docs.
Reading events and snapshots
Next to the API to publish events and snapshots to Axon Server, there is also an HTTP API to read aggregate events and snapshots from the Axon Server event store. The next sections describe the provided operations.
Read aggregate events
The endpoint /v2/aggregates/[aggregate-id]/events?context=[context]
returns all the events for the given aggregate. It is
possible to reduce the number of events returned by specifying the minSequence
parameter. This will only return the events with a sequence number equal to or larger than the given value.
The result of the operation is a list of event messages starting with the event with the lowest sequence number.
Read aggregate events (paged)
The endpoint /v2/aggregates/[aggregate-id]/eventsPaged?context=[context]&pageOffset=[offset]&pageSize=[pageSize]
returns one page of events for the given aggregate.
The result of the operation is a list of event messages starting with the event with the lowest sequence number.
Read aggregate snapshots
The endpoint /v2/aggregates/[aggregate-id]/snapshots?context=[context]
returns snapshots for the given aggregate.
It is possible to reduce the number of snapshots returned by specifying the minSequence
and/or maxResults
parameter.
The maxResults
parameter, default value is one, determines how many snapshots will be returned.
The minSequence
parameter ensures that the operation will only return the snapshots with a sequence number equal to or larger than the given value.
The result of the operation is a list of snapshot messages, starting with the snapshot with the highest sequence number.