Output Configuration

In general, each Web service has an associated invocation index, which is an index that stores the metadata for each invocation.

This metadata includes a unique ID, the timestamp, the inputs, and the output of the invocation.

The output configuration in your Web service class is where you specify the structure of the returned data and where it is stored. With regards to where data is stored, there are two categories: - Storing non-nested data in the invocation index with the invocation metadata - Storing complex data in dedicated indices outside the invocation index

Storing data in the invocation index

For simple data, it is sometimes not necessary to create a dedicated index for the data, as it can be simple and small enough data to fit in with the metadata:

// Example of document containing invocation metadata as well as result data for an MD5 hashing service
{
  "invocation_uuid": "07cd7f20-0090-11ea-9e5d-6581d32cc2d2",
  "timestamp": 1573042919442,
  "user": "john-stone",
  "input": {
    "string": "my-secret-password"
  },
  "output": {
    "hash": "a2d9679c7fff3e9cf4300a2cc3fbad79"
  }
}

To specify an output configuration that gets results stored in the invocation index like this, use a single nested object for the outputConfiguration attribute:

readonly outputConfiguration: OutputConfiguration = {
  hash: 'text'
};

The output can have as many fields as you want, but must not be nested. The result of the invoke function must be a list of objects that match this structure:

async invoke(params: object): Promise<SimpleMap> {
  return {
    hash: md5(params.string)
  };
}

A list is used to facilitate returning multiple results with the same structure for a single invocation.

Storing data in dedicated data indices

For services that return more complex results, or different types of results, dedicated indices may be used. The output configuration specifies an index name fragment and the structure of the data:

// Of the form:
//   {
//     "index-name-fragment": {
//       "field": "type"
//     }
//   }
readonly outputConfiguration: OutputConfiguration = {
  person: {
    first_name: 'keyword',
    surname: 'keyword',
    age: 'long'
  },
  company: {
    name: 'keyword',
    address: 'text',
    isLimitedLiability: 'boolean'
  }
};

This output configuration specifies that the service returns objects that should be stored in dedicated indices. The index names used for storage is of the form web-service-{serviceGroup}-{serviceName}-results-{fragment}, so the above configuration directs the results to be stored in the following indices: - web-service-crunchbase-search-results-person - web-service-crunchbase-search-results-company

This naming is used to avoid conflicts with other Web services.

Given the above output configuration, the output of the invoke method is an object that specifies the indices each object must be stored in:

async invoke(params: object): Promise<ExternalIndexMappings> {
  const results = await queryCrunchbaseApi(params);
  return {
    person: [{
      first_name: results[0].owner.firstName,
      surname: results[0].owner.surname,
      age: results[0].owner.age
    }],
    company: [{
      name: results[0].name,
      address: results[0].location.address,
      isLimitedLiability: results[0].structure === 'llc'
    }]
  };
}

Variable-response Web services

There is a class of Web services that do not store data in Elasticsearch. This allows them to return data that is not predefined. These are called variable-response Web services.

A Web service can be denoted as such by setting the outputConfiguration to undefined, which implies that the response can take any form, or even be empty:

readonly outputConfiguration = undefined;

This Web service will not show up in the Web Services dashboard, as this dashboard relies on storing result data in Elasticsearch in order to present it.

Variable-response Web services can only be invoked by using the Siren scripting API. For more information, see Invoking Web services.

By default, invocation metadata is not stored in Elasticsearch. To store this metadata, such as timestamp, inputs of the query, and so on, set the keepInvocationHistory parameter to true:

readonly keepInvocationHistory = true;