Skip to content

Data Processing

APICHAP configuration comes with a data processing syntax:

  1. Methods
  2. Json Schema Generation
  3. Conditions
  4. Placeholders

Methods

One of the major concepts of APICHAP is the usage of methods to get, filter and transform data. Methods are expecting input parameters and will return values. You are also able to combine multiple methods into one.

Overview

Field Parameter 1 Parameter 2 Description
VALUE The data defined with a fulfillment name or BODY() JSONPATH syntax A method to run a JSONPATH on a JSON.
PARAM Query/Header Parametername - Get the value for a certain request input parameter.
BODY - - Get the request body (if available).
TEXT Text - Set a hardcoded text.
INTEGER Number - Set a hardcoded integer.
DOUBLE Number including decimal - Set a hardcoded double.
BOOLEAN true or false - Set a hardcoded boolean.
NULL - - The value null.
JSON_FROM_STRING JSON - Used to decode a json from string attribute.
LIST Array size - Build an empty list with the size of Parameter 1.
SIZE A Json Array - Get the size of a Json Array.
MULTIPART_FILE The multipart key (from the request) - Read the filestream from the incoming request by using the multipart key.
MULTIPART_FILENAME The multipart key (from the request) - Get the filename from the incoming request by using the multipart key.
GET_JSON A fulfillment name - Get the result from a fulfillment a json.
LIST_TO_STRING 4 Parameters (see details below) - Build a string from a list of string, with the options for prefixes and seperator.
VALUE_BY_INDEX 3 Parameters (see details below) - Retrieve a value of an indexed fulfillment.

Roadmap: We will constantly extend our list of possible methods.

VALUE

With the value function you are able to access data (like from other fulfillment results) and get specific values from the JSON by using the JSONPATH syntax.

VALUE(param1, param2)

Param 1 - Input JSON

The input JSON could originate from various datasets:

Parameter 1 Example Description
Fulfillment Name VALUE(ff_name_1, JSONPATH) Access the result (data) of a fulfillment.
BODY() VALUE(BODY(), JSONPATH) Access the requestbody of the current request. For example the JSON body in a POST request.
@ VALUE(@, JSONPATH) When building Json Array you may use the @ to access the current entry in a loop.
JSON_FROM_STRING VALUE(@, JSONPATH) Get a JSON from another escaped JSON field.
Fulfillment Result

Every result from a fulfillment is transformed into a JSON and accessable with the VALUE method.

A result from a database is transformed into a JSON as well, which you can then filter for your response as needed.

The result from a database is transformed in the following JSON set to work with:

Database

id title description
1 News 1 Newsttext 1
2 News 2 Newstext 2

JSON

[
  {
    "id": 1, 
    "title": "News 1",
    "description": "Newsttext 1"
  },
  {
    "id": 2,
    "title": "News 2",
    "description": "Newsttext 2"
  }
]

A database query always produces a JSON Array, because we don´t know how many results are returned in a query.

Insert, Update & Generated Key

When running an INSERT or UPDATE statement APICHAP will always get the Generated Key from the database. Depending on your database the Generated Key looks differently:

Database Get Generated Keys
MariaDb If you run an INSERT command with an auto-incremental ID, you can use VALUE(fulfillment_name, $.insert_id) afterward which provides the generated id.
PostgreSQL PostgreSQL will deliver all columns that have been created in the INSERT/UPDATE query. Just like if you would query a select. VALUE(fulfillment_name, $.id)
MSSQL You will get the auto-incremental ID as GENERATED_KEYS. e.g.: VALUE(fulfillment_name, $[0].GENERATED_KEYS))

Param 2 - JSONPATH syntax

Your jsonpath syntax. See the documentation for more information.

HINT Use the JSONPATH Online Syntax Editor for testing your syntax: https://jsonpath.com

PARAM

Get the value for a certain request input parameter. You may request both query or header parameters this way.

PARAM(Content-Language)
PARAM(userId)

BODY

Get the request body as JSON (if available).

BODY()

TEXT

Set a hardcoded text. Whenever you just need to set a hardcoded text/string, you may do this with the method TEXT(string)

TEXT(This is an example text)
TEXT(I can put every hardcoded string in here!)
TEXT() ## emtpy string, useful for condition comparison.

INTEGER

Set a hardcoded integer.

INTEGER(0)
INTEGER(150)
INTEGER(-210)

DOUBLE

Set a hardcoded double.

DOUBLE(1.3)
DOUBLE(15.82)

BOOLEAN

Set a hardcoded boolean.

BOOLEAN(true)
BOOLEAN(false)

NULL

When building a condition you sometimes want to check for null values. Use the NULL() method for that.

NULL()

JSON_FROM_STRING

Used to decode a JSON from string attribute. This is usable for results you get from a 3rd party request or database columns where an escaped JSON input is within a attribute. After escaping a JSON you may use it within a VALUE method to filter.

Used in combination with a VALUE method.

JSON_FROM_STRING(VALUE(fulfillment_name, $.content.escapedjson)

LIST

Returns a list with an index (starting with 1). You may use List to build Loop fulfillments with a hardcoded number of iterations, or for building a request schema with a fixed size.

LIST(1)
LIST(3)

Example on usage:

  - name: loop_ff
    type: loop
    loop: LIST(20)
    fulfillments:

      - name: ff_example
        type: READ
        datasource: api
        instructions:
          - request:
              ## Use VALUE(loop_ff, $) to get the current index of the loop LIST() starting with 1.
              url: "https://www.example.com?page=:[VALUE(loop_ff, $)]
              httpType: GET

SIZE

Get the size of a JSON Array. Used in combination with the VALUE method.

SIZE(VALUE(fulfillment_name, $))
SIZE(VALUE(fulfillment_name, $.news))

MULTIPART_FILE

Read the filestream from the incoming request by using the multipart key.

MULTIPART_FILE(multipart_key)
MULTIPART_FILE(file)

MULTIPART_FILENAME

Get the filename from the incoming request by using the multipart key.

MULTIPART_FILENAME(multipart_key)
MULTIPART_FILENAME(file)

GET_JSON

Get the result from a fulfillment a json.

GET_JSON(fulfillment_name)
GET_JSON(ff1)

LIST_TO_STRING

Build a string from a list of string, with the options for prefixes and seperator.

LIST_TO_STRING(fulfillment_name, JsonPath, Prefix (Use %s as placeholder for your list value), Seperator)
LIST_TO_STRING(ffname, $.list, "entry:%s", "||")
LIST_TO_STRING(ffname, $.list, "Placeholder %s here", "")

VALUE_BY_INDEX

If you have a fulfillment which is running multiple times in a loop, it makes sense to index this fulfillment. After doing so you are able to access indexed fulfillments by using the VALUE_BY_INDEX method. Add the fulfillment name and the index as second parameter to get the result. The second parameter must be from another method such as VALUE or NUMBER, TEXT.

VALUE_BY_INDEX(Fulfillment Name, Index Value, JsonPath)
VALUE_BY_INDEX(ff1, INTEGER(1), $.list)
VALUE_BY_INDEX(ff1, VALUE(ff2, $.id), $.list)

Json Schema Generation

Within a configuration you might need to build JSON schemas on different occasions:

  • API Response
  • API Exception Response
  • Requestbody to send to 3rd party API requests

In all of those occasions the configuration structure to build them is exactly the same.

General

A JSON structure can be build using those types:

Simple Value

Specify a primitive JSON attribute by setting key: value to your yaml configuration.

It´s possible to concat simple string values with + (see second example).

Configuration Result
schema:
  firstname: VALUE(contact, $.results[0].properties.firstname)
{
    "firstname": "Maria"
}
schema:
  animals: TEXT(List of Animals ) + LIST_TO_STRING(ff1, $.animals, "* %s", "|")
{
    "animals": "List of Animals * Dog | * Cat | * Bird"
}

List (Array)

Specify a JSON array with the following attributes:

Field Description
list Specify the a JSON array, used to loop through and build the JSON objects below.
item Either a new object or direct value (primitive, like a string array).
Configuration Result
> Use @ the current iteration of the list.
schema:
  # Value needs to be an array
  list: VALUE(fulfillment_contacts, $.persons) 
  item:
    firstname: VALUE(@, $.firstname) # Specify a @ value
    ...
[
  {
    "firstname": "Maria"
  }, {
    "firstname": "Alex"
  }
]
schema:
  # Value needs to be an array
  list: VALUE(fulfillment_contacts, $.persons) 
  item: VALUE(@, $.firstname) # Specify a primitive value directly.
[
  "Maria", 
  "Alex"
]
> You are able to use @@ to get the iteration from before and so on.
schema:
  # Value needs to be an array
  list: VALUE(fulfillment_contacts, $.groups) 
  item: 
    list: VALUE(@, $.persons)
    item:
      firstname: VALUE(@, $.firstname) # Specify a primitive value directly.
      groupName: VALUE(@@, $.group_name) # Specify a group name.
[
  "Maria", 
  "Alex"
]

Object

Specify a JSON object with the following attributes:

Field Description
object OPTIONAL; Specify data to be used with @ in your object
item Your Object
Configuration Result
schema:
  person:
    # Specify an object without using the object attribute
    item:
      firstname: VALUE(person_ff, $.person.firstname) 
      lastname:  VALUE(person_ff, $.person.lastname) 
{
  "person": {
    "firstname": "Maria",
    "lastname": "Volovik"
  }
}
schema:
  person:
    # Specify with an object to use the @ syntax below.
    object: VALUE(person_ff, $.person) 
    item: 
      firstname: VALUE(@, $.firstname) 
      lastname:  VALUE(@, $.lastname)
{
  "person": {
    "firstname": "Maria",
    "lastname": "Volovik"
  }
}

Map (Dictionary)

Specify a JSON map (dictionary) with the following attributes

Field Description
map Specify the map or dictionary.
item Your Map Object or direct mapping.
Configuration Result
schema:
  person:
    # Set the whole dictionary person into our person field. 
    # The input VALUE must be a dictionary.
    map: VALUE(person_ff, $.person)
{
  "person": {
    "firstname": "Maria",
    "lastname": "Volovik",
    "age": 32
  }
}
schema:
  person: 
    map: VALUE(person_ff, $.person) # Value must be an object
    item: 
      # Specify an object without using the object attribute
      firstname: VALUE(@, $.firstname) 
{
  "person": {
    "firstname": "Maria"
  }
}

Full Example

A full response builder could look like that:

schema:
  list: VALUE(get_news, $) # Needs to be an array
  items:
    id: VALUE(@, $.id) # Needs to be an array
    title: VALUE(@, $.name) # Needs to be an array
    authors:
      list: VALUE(authors, $)
      items:
        firstname: VALUE(@, $.firstname)
        lastname: VALUE(@, $.firstname)
    news_time: VALUE(@, $.newstime)

Building the following JSON result:

[
  {
    "id": 1, 
    "title": "APICHAP v1 is out now!",
    "authors": [
      {
        "firstname": "Alex",
        "lastname": "Lee"
      },{
        "firstname": "Maria",
        "lastname": "Mustermann"
      },
    ],
    "news_time": "2024-04-25T13:01:40+00:00"
  }, 
  {
    "id": 2,
    "title": "Amazing Devtool Released",
    "authors": [
      {
        "firstname": "Alex",
        "lastname": "Lee"
      }
    ],
    "news_time": "2024-04-25T15:01:40+00:00"
  }
]

Condition

In multiple occasions you will need to specify a condition for an if attribute.

Operator Description
== Two values are equal.
!= Two values are not equal.
< Value 1 is smaller then value 2
<= Value 1 is smaller or equal to value 2
> Value 1 is bigger then value 2
>= Value 1 is bigger or equal to value 2
# Check if input parameter is english
PARAM(Content-Language) == TEXT(en)
# Check if input parameter id is not equal to the result of ff1.id
PARAM(Content-Language) != VALUE(ff1, $.id)
# Check if the field age from result of fulfillment called ff1 is bigger then 30
VALUE(ff1, $.age) > INTEGER(30)

Placeholder

Whenever you use a method within another string, like: in queries, request url´s, method parameters, you have to set your value within a placeholder.

:[PLACEHOLDER VALUE]

# Placeholder for the Header Parameter Content-Language
SELECT * FROM news WHERE lang == :[PARAM(Content-Language)]
# Placeholder for a Path Parameter called id
SELECT * FROM news WHERE id == :[PARAM(id)]
# Placeholder for a field userid retrieved from the requestbody json: { "userid":"1", "username":"Maria" }
SELECT * FROM user WHERE id == :[VALUE(BODY(), $.userid)]
# Placeholder to use a value called id from a fulfillments (fulfillment name: ff1) result. 
SELECT * FROM notes_changelog WHERE notes_id == :[VALUE(ff1, $.id)]

Escape square brackets

Attention If you use a square bracket in a placeholder you must escape it with \

SELECT * FROM notes WHERE notes_id == :[VALUE(fulfillment_name, $\[0\].GENERATED_KEYS))]