Skip to main content

04 - Validating & Testing Data

Continuing from the previous section, we will now look at understanding how we can validate our incoming input data, or any data involved in action.

This section briefly starts to show you how we can build workflows by controlling the order of actions.

Assertions

A highly configurable assertion & test framework is built into the platform for you to leverage, see all the available options here.

Steps

1. HTTP GET API with Input Validation

In this simple example we will be creating a HTTP GET API where we will validate the input data and then call another API endpoint and use a query parameter to specify an id parameter to fetch a specific comment.

Deploy via Hosted / Managed

Deploy via Self Hosted / Unmanaged

  • A configs directory should have been created automatically for you, else create one.
  • Copy the below example config into your configs directory, eg.
        configs/04-http-get-validate.yml
  • Stop/Start airpipe eg.
    ./airpipe server --api-key your-api-key --config-dir configs

Example Config

Deploy
HTTP GET API with Input Validation
loading...

Test

Hosted mode, either navigate to or curl:

  • The load configuration UI will automatically show you what your detected routes are, you can copy this for the next steps.

  • The link is automatically built with your organization uuid and environment, your API endpoints can be found here if required https://app.airpipe.io/configurations.

  • Update the route as necessary

curl https://api.airpipe.io/your_org_id/staging/tutorial/validate?id=1&first=panther

Self hosted mode, either navigate to or curl:

http://0.0.0.0:4111/tutorial/validate?id=1&first=panther

curl http://0.0.0.0:4111/tutorial/validate?id=1&first=panther

Observations

If you used the exact same query parameters as supplied above, you will get the below response, where an errors parameter has now been added and indicates the first value has failed validation.

The id existed and did not throw an error, and was succesfully used in the subsequent action GetData.

Response

{
"data": {
"CheckParams": {
"data": {
"first": "panther",
"id": "1"
},
"errors": [
"first::is_less_than: expected target panther not less than 5"
],
"time.ms": 0
},
"GetData": {
"data": {
"body": {
"body": "laudantium enim quasi est quidem magnam voluptate ipsam eos\ntempora quo necessitatibus\ndolor quam autem quasi\nreiciendis et nam sapiente accusantium",
"email": "[email protected]",
"id": 1,
"name": "id labore ex et quam laborum",
"postId": 1
},
"headers": {
"accept-ranges": "bytes",
"access-control-allow-credentials": "true",
"age": "7758",
"alt-svc": "h3=\":443\"; ma=86400",
"cache-control": "max-age=43200",
"cf-cache-status": "HIT",
"cf-ray": "883c4494f9a981c4-IAD",
"content-length": "268",
"content-type": "application/json; charset=utf-8",
"date": "Tue, 14 May 2024 16:29:34 GMT",
"etag": "W/\"10c-KJ4I9RM/+33TKdV8CFsIvqsDSP0\"",
"expires": "-1",
"nel": "{\"report_to\":\"heroku-nel\",\"max_age\":3600,\"success_fraction\":0.005,\"failure_fraction\":0.05,\"response_headers\":[\"Via\"]}",
"pragma": "no-cache",
"report-to": "{\"group\":\"heroku-nel\",\"max_age\":3600,\"endpoints\":[{\"url\":\"https://nel.heroku.com/reports?ts=1715432434&sid=e11707d5-02a7-43ef-b45e-2cf4d2036f7d&s=unAGx%2FNj2kC7aw%2BJo6jqZ5aN559MvyKIxP1xTVZgHcw%3D\"}]}",
"reporting-endpoints": "heroku-nel=https://nel.heroku.com/reports?ts=1715432434&sid=e11707d5-02a7-43ef-b45e-2cf4d2036f7d&s=unAGx%2FNj2kC7aw%2BJo6jqZ5aN559MvyKIxP1xTVZgHcw%3D",
"server": "cloudflare",
"vary": "Origin, Accept-Encoding",
"via": "1.1 vegur",
"x-content-type-options": "nosniff",
"x-powered-by": "Express",
"x-ratelimit-limit": "1000",
"x-ratelimit-remaining": "999",
"x-ratelimit-reset": "1715432467"
},
"status": 200
},
"time.ms": 33
}
}
}

2. Perform action on success

We will build upon the prior example and make a simple change from depends_on to run_when_succeeded to enforce that the first action should be successful before continuing to the next.

Deploy via Hosted / Managed

Deploy via Self Hosted / Unmanaged

  • A configs directory should have been created automatically for you, else create one.
  • Copy the below example config into your configs directory, eg.
        configs/04-http-get-validate.yml
  • Stop/Start airpipe eg.
    ./airpipe server --api-key your-api-key --config-dir configs

Example Config

Deploy
HTTP GET API with Input Validation
loading...

Test

Hosted mode, either navigate to or curl:

  • The load configuration UI will automatically show you what your detected routes are, you can copy this for the next steps.

  • The link is automatically built with your organization uuid and environment, your API endpoints can be found here if required https://app.airpipe.io/configurations.

  • Update the route as necessary

curl https://api.airpipe.io/your_org_id/staging/tutorial/validate-success?id=1&first=panther

Self hosted mode, either navigate to or curl:

http://0.0.0.0:4111/tutorial/validate-success?id=1&first=panther

curl http://0.0.0.0:4111/tutorial/validate-success?id=1&first=panther

Observations

If you used the exact same query parameters as supplied above, you will get the below response, where an errors parameter has now been added and indicates the first value has failed validation.

Additionally you will now see that the GetData action was not performed and returned an error stating that CheckParams did not succeed.

If you update the first parameter for eg. from panther to leo, you will notice that the GetData action will be performed with no errors returned.

Failure Response

{
"data": {
"CheckParams": {
"data": {
"first": "panther",
"id": "1"
},
"errors": [
"first::is_less_than: expected target panther not less than 5"
],
"time.ms": 0
},
"GetData": {
"data": null,
"error": "previous action 'CheckParams' did not succeed",
"time.ms": 0
}
}
}

2. Perform action on failure

Simply update depends_on or run_when_succeeded to run_when_failed.

3. Advanced combination use cases

It is completely possible to use depends_on, run_when_succeeded and run_when_failed together in a single action.

This is completely dependent on your own circumstances.

4. All assertion and test configuration

Review the assertion section here.