Skip to main content

Connections

webhook

Commentary

added in 0.0.5

Sends events to a webhook using a JSON encoded body.

To increase the concurrency of outstanding HTTP requests, you may want to increase the maximum number of open files in the Docker container, otherwise known as the ulimit, and increase the corresponding maxRequests. 1


Examples

Configuring the connection

This connection takes no further configuration. All parameterization takes place in the generator.

{
"connections": {
"saas-webhook": {
"kind": "webhook"
}
}
}

Generating data

Minimally, use url to specify the route to send data to.

{
"generators": [
{
"url": "http://my-url.com/route",
"data": {
"latency": {
"_gen": "normalDistribution",
"mean": 100,
"sd": 10,
"decimals": 1
}
}
}
],
"connections": {
"saas-webhook": {
"kind": "webhook"
}
}
}

Set the method

Use method to set the HTTP method of the request. If left unset, it defaults to POST.

{
"generators": [
{
"url": "http://my-url.com/route",
"method": "PUT",
"data": {
"_gen": "boolean"
}
}
],
"connections": {
"saas-webhook": {
"kind": "webhook"
}
}
}

Set headers

Set headers to an object of values to control the HTTP request headers. Because body data is serialized with JSON, content-type is always set to application/json.

{
"generators": [
{
"url": "http://my-url.com/route",
"headers": {
"X-API_KEY": {
"_gen": "env",
"var": "MY_API_KEY"
}
},
"data": {
"_gen": "oneOf",
"choices": [
"a",
"b",
"c"
]
}
}
],
"connections": {
"saas-webhook": {
"kind": "webhook"
}
}
}

Set query parameters

Set queryParams to an object of key/value pairs to set the query string on the URL.

{
"generators": [
{
"url": "http://my-url.com/route",
"queryParams": {
"foo": "bar",
"baz": "bip"
},
"data": {
"_gen": "oneOf",
"choices": [
1,
2
]
}
}
],
"connections": {
"saas-webhook": {
"kind": "webhook"
}
}
}

Vary the URL

Use urlSuffix to send requests to a varied URL. urlSuffix is optional and dynamic, so it's useful if you want to generate data to a series of URLs over time.

In the example below, three requests are send to:

  1. http://localhost:8080/a, with method PUT
  2. http://localhost:8080/b, with method POST
  3. http://localhost:8080/c, with method GET

Note that because requests are send asynchronously by default, they may be received in a different order than expected. Consider using synchronous requests if order is important. 2

{
"generators": [
{
"url": "http://localhost:8080",
"data": {
"status": {
"_gen": "boolean"
}
},
"stateMachine": {
"_gen": "stateMachine",
"initial": "A",
"transitions": {
"A": "B",
"B": "C"
},
"states": {
"A": {
"urlSuffix": "/a",
"method": "POST"
},
"B": {
"urlSuffix": "/b",
"method": "PUT"
},
"C": {
"urlSuffix": "/c",
"method": "GET"
}
}
}
}
],
"connections": {
"saas-webhook": {
"kind": "webhook"
}
}
}

Increase the concurrency

Use maxRequests to increase the number of concurrent, outstanding HTTP requests pending at any given time. The default is 20000. Make sure this value is lower than the soft ulimit of your Docker container, otherwise you may encounter errors.

{
"generators": [
{
"url": "http://my-url.com/route",
"data": {
"latency": {
"_gen": "uniformDistribution",
"bounds": [
5,
10
]
}
}
}
],
"connections": {
"saas-webhook": {
"kind": "webhook",
"connectionConfigs": {
"maxRequests": 50000
}
}
}
}

Synchronous requests

Set maxRequests to 0 to force all requests to execute and complete in sequential order. This can be especially useful for simulating aplications that never use asynchronous communication.

{
"generators": [
{
"url": "http://my-url.com/route",
"data": {
"latency": {
"_gen": "normalDistribution",
"mean": 10,
"sd": 2
}
}
}
],
"connections": {
"saas-webhook": {
"kind": "webhook",
"connectionConfigs": {
"maxRequests": 0
}
}
}
}

Log request/response pairs

If your webhook calls aren't doing what you expect them to, it can be useful inspect the request/response pairs for debugging purposes. Set printExchange to true in the connection map to log them to standard out.

{
"generators": [
{
"url": "http://my-url.com/route",
"data": {
"_gen": "oneOf",
"choices": [
"a",
"b",
"c"
]
}
}
],
"connections": {
"saas-webhook": {
"kind": "webhook",
"printExchange": true
}
}
}

Your output will look like the following:

------- start request/response pair -------
request:
{
"method" : "POST",
"url" : "http://localhost:55383/foo",
"body" : "{\"latency\":true}",
"query-params" : {
"foo" : "bar"
},
"headers" : {
"a" : "b",
"content-type" : "application/json"
}
}
response:
{
"request-time" : 2,
"aleph/keep-alive?" : true,
"headers" : {
"server" : "Aleph/0.8.1",
"content-length" : "0",
"connection" : "Keep-Alive",
"date" : "Wed, 26 Feb 2025 19:31:35 GMT"
},
"status" : 200,
"connection-time" : 1,
"body" : ""
}
------- end request/response pair -------

Specification

Connection JSON schema

{
"type": "object",
"properties": {
"kind": {
"type": "string",
"const": "webhook"
},
"printExchange": {
"type": "boolean"
},
"connectionConfigs": {
"type": "object",
"properties": {
"maxRequests": {
"type": "number",
"minimum": 0
}
}
}
}
}

Generator JSON schema

{
"type": "object",
"properties": {
"url": {
"type": "string"
},
"localConfigs": {
"type": "object",
"properties": {
"throttleMs": {
"oneOf": [
{
"type": "number",
"minimum": 0
},
{
"type": "object",
"properties": {
"_gen": {
"type": "string"
}
},
"required": [
"_gen"
]
}
]
},
"maxEvents": {
"oneOf": [
{
"type": "integer",
"minimum": 0
},
{
"type": "object",
"properties": {
"_gen": {
"type": "string"
}
},
"required": [
"_gen"
]
}
]
},
"kafkaKeyProtobufHint": {
"type": "object",
"properties": {
"schemaFile": {
"type": "string"
},
"message": {
"type": "string"
}
},
"required": [
"schemaFile",
"message"
]
},
"jsonSchemaHint": {
"type": "object"
},
"maxBytes": {
"type": "integer",
"minimum": 1
},
"discard": {
"type": "object",
"properties": {
"rate": {
"type": "number",
"minimum": 0,
"maximum": 1
},
"retainHistory": {
"type": "boolean"
}
},
"required": [
"rate"
]
},
"repeat": {
"type": "object",
"properties": {
"rate": {
"type": "number",
"minimum": 0,
"maximum": 1
},
"times": {
"oneOf": [
{
"type": "integer",
"minimum": 0
},
{
"type": "object",
"properties": {
"_gen": {
"type": "string"
}
},
"required": [
"_gen"
]
}
]
}
},
"required": [
"rate",
"times"
]
},
"protobufSchemaHint": {
"type": "object",
"patternProperties": {
"^.*$": {
"type": "object",
"properties": {
"schemaFile": {
"type": "string"
},
"message": {
"type": "string"
}
},
"required": [
"schemaFile",
"message"
]
}
}
},
"maxHistoryEvents": {
"type": "integer",
"minimum": 0
},
"maxMs": {
"type": "integer",
"minimum": 0
},
"time": {
"type": "integer"
},
"events": {
"type": "object",
"properties": {
"exactly": {
"oneOf": [
{
"type": "integer",
"minimum": 0
},
{
"type": "object",
"properties": {
"_gen": {
"type": "string"
}
},
"required": [
"_gen"
]
}
]
}
}
},
"delay": {
"type": "object",
"properties": {
"rate": {
"type": "number",
"minimum": 0,
"maximum": 1
},
"ms": {
"oneOf": [
{
"type": "integer",
"minimum": 0
},
{
"type": "object",
"properties": {
"_gen": {
"type": "string"
}
},
"required": [
"_gen"
]
}
]
}
},
"required": [
"rate",
"ms"
]
},
"history": {
"type": "object",
"properties": {
"events": {
"type": "object",
"properties": {
"max": {
"type": "integer",
"minimum": 0
}
}
}
}
},
"avroSchemaHint": {
"type": "object"
},
"throttle": {
"type": "object",
"properties": {
"ms": {
"oneOf": [
{
"type": "number",
"minimum": 0
},
{
"type": "object",
"properties": {
"_gen": {
"type": "string"
}
},
"required": [
"_gen"
]
}
]
}
}
},
"throughput": {
"oneOf": [
{
"type": "integer",
"minimum": 1
},
{
"type": "object",
"properties": {
"_gen": {
"type": "string"
}
},
"required": [
"_gen"
]
}
]
},
"timeMultiplier": {
"oneOf": [
{
"type": "number"
},
{
"type": "object",
"properties": {
"_gen": {
"type": "string"
}
},
"required": [
"_gen"
]
}
]
},
"kafkaValueProtobufHint": {
"type": "object",
"properties": {
"schemaFile": {
"type": "string"
},
"message": {
"type": "string"
}
},
"required": [
"schemaFile",
"message"
]
}
}
},
"method": {
"type": "string"
},
"name": {
"type": "string"
},
"connection": {
"type": "string"
},
"queryParams": {
"type": "object"
},
"data": {},
"urlSuffix": {
"oneOf": [
{
"type": "string"
},
{
"type": "object",
"properties": {
"_gen": {
"type": "string"
}
},
"required": [
"_gen"
]
}
]
},
"headers": {
"type": "object"
}
},
"required": [
"url",
"data"
]
}