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:
http://localhost:8080/a
, with methodPUT
http://localhost:8080/b
, with methodPOST
http://localhost:8080/c
, with methodGET
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"
]
}