Call REST Action

The action module for this action is "vb/action/builtin/restAction".

The call REST action is used to make a REST call in conjunction with the service definitions. Internally, this action uses the Rest Helper, which is a public utility. Its parameters are as follows:

Parameters:

Parameter Name Description
endpoint The endpoint ID as defined in the service configuration.
uriParams A key/value pair map that will be used to override path and query parameters as defined in the service endpoint.
body A structured object that will be sent as the body.
requestType The content-type of the request, either 'json', 'form', or 'url'.

Note:

Note that this is deprecated. Instead, use 'contentType' and 'fileType'.
headers An object; each property name is a header name and value that will be sent with the request.
contentType An optional string value with an actual MIME type, which will be used for the "content-type" header. When used with "fileType", this is also used as the type for the File blob.
responseType If a responseType is set, coerce the REST response body to this type.
filePath An optional path to a file to send with the request. If "contentType" is set, that is used as the type for the File contents. If “contentType” is not set, a lookup of common file extensions will be used.
fileContentType An optional string, used in combination with "contentType", "multipart/form-data", and "filePath".
hookHandler Used primarily by vb/ServiceDataProvider when externalizing data fetches. See ServiceDataProvider for details.
requestTransformOptions A map of values to pass to the corresponding transform, as the "options" parameter.
requestTransformFunctions A map of named transform functions, called before making the request, where the function is: fn(configuration, options)
responseTransformFunctions A map of named transform functions, called before making the response, where the function is: fn(configuration, options)
responseBodyFormat  A string that allows an override of the standard Rest behavior which looks for a “content-type” header to determine how to read and parse the response. Possible values are "text", "json", "blob", "arrayBuffer", "base64", "base64Url", and "formData".

Using mutipart/form-data

If you have set "contentType" to "multipart/form-data", the Action will interpret your request "body" object as the form parts. Each property of the body object will be a form part. If "filePath" is also set, it will be added as an additional part using the lookup of common file extension types.

If "filePath" is also set, it will be added as an additional part using the sample simple file extension type association. The name of this part will be "file", or can be specified using "filePartName".

You may optionally override the file type by using "fileContentType" for the file part.

Transforms

The requestTransformOptions, requestTransformFunctions, and responseTransformFunctions can be used to modify the request and response. Some built-in service endpoints have transform functions for 'sort', 'filter', 'paginate', 'select'. Options for these transform functions can be defined using the same name via the requestTransformOptions property. For third party services, the options set are based on the type of transform functions supported.

When using the Rest Action the transforms names have no semantic meaning, and all request and response transforms are called.

Table 8-1 Request and Response Transforms

Transform type Parameters Return Value
Request
/**
 * configuration: {
 *  url:
 *   initConfig: {
 *     method: // string with http method
 *     body: // request body, if any
 *     credentials: // string see (fetch) Request
 *     headers: // object, map of strings
 *   }
 * },
 *
 * options: provided by the application
 *
 * context: an empty object, which exists for the
 *   lifetime of one REST call, a set of 
 *   transforms share this.
 **/
 
mytransform(configuration, options, context)

Configuration object; see "Parameters".

Typically, returns the same object passed in, or a modified one.

Response
/**
 * response: { body, headers }
 *
 * context: an empty object, see "Request transforms"
 *
 */
myresponsetransform(response, context);
The return value is application-defined. The value is returned as the 'transformResults' of the REST call result:
/**
 * {
 *  response: The (fetch) Response object. Note that the body has already
 *     been read, so the functions (ex. json()) cannot be called.
 *
 *  body: the result of the json()/text()/etc.
 * 
 *  transformResults: a map of return values from Response Transforms
 * }
 */

Table 8-2 Outcomes

Outcome Description Result Payload
success

If the response code is within the 200 range (or 'ok' in fetch API terms).

  • status: number
  • headers: Headers object
  • body: the result of the call (scalar, obejct, array, etc).
{
  status: <responseCode>,
  headers: <responseHeaders>,
  body: <result body>
}
failure

If the response code is outside of the 200 range (an error response).

  • message

    • summary: string
  • error: Error object, or null
  • payload
    • status: number
    • headers: Headers object
    • body: the result of the call (scalar, obejct, array, etc).
{
  message: {
    summary: <rt message>
  },
  error: <Error, or null>,
  payload: {
    status: <responseCode>,
    headers: <responseHeaders>,
    body: <result body>
  }
}

Example 8-15 Defining Services

In order to use a REST API, it should be first defined.

In this example, the following endpoint is registered for the 'foo' service:

{
  "swagger": "2.0",
  "info": {
    "version": "1.1",
    "title": "ifixitfast",
    "description": "FIF",
  },
  "host": "domain.com",
  "basePath": "/services/root",
  "schemes": [
    "http"
  ],
  "paths": {
    "/foo/{id}": {
      "get": {
        "summary": "get a specific Foo object",
        "operationId": "getBar",
        "parameters": [
           {
            "name": "id",
            "in": "path",
            "required": true,
            "type": "string"
           }
        ],
        "responses": {
          "200": {
            "description": "",
            "schema": {}
          }
        }
      }
    }
  }
}

You can invoke that endpoint with the following, passing in a value for the 'id' path parameter from a page parameter:

"myActionChain": {
  "root": "myAction",
  "actions": {
    "myAction": {
      "module": "vb/action/builtin/restAction",
      "parameters": {
        "endpoint": "foo/getBar",
        "uriParams": { 
          "id": "{{ $page.variables.myId }}"
        }
      }
    }
  }
}

Example 8-16 Declaring Services in the Application

Service definitions are referenced in declarations in the application or in flows. The service name and path are defined by a "services" section in an app-flo.json or xxx-flow.json model. Service declarations support two syntaxes: a string (path), or an object with "path" and "headers":

"services": {
  "fooService": "./demo-data-service.json",
  "barService": {
     "path":  "./service-def.json",
     "headers": {
        "Accept": "application/vnd.oracle.openapi3+json"
     }
  }
}

Example 8-17 Referencing Endpoints

You can invoke the endpoint with the following, passing a value for the 'id' path parameter from a page parameter:

"myActionChain": {
  "root": "myAction",
  "actions": {
    "myAction": {
      "module": "vb/action/builtin/restAction",
      "parameters": {
        "endpoint": "fooService/getBar",
        "uriParams": { 
          "id": "{{ $page.variables.myId }}"
        }
      }
    }
  }
}

Example 8-18 A Simple Transform Function

One request transform function, and one response transform function for a third party service or endpoint, might look like this example. Here, the transform functions are defined in the page module and are configured on the RestAction directly. More commonly, transform functions are defined in the service definition and do not need to be mapped on the RestAction.

"fetchIncidentList": {
  "module": "vb/action/builtin/restAction",
  "parameters": {
    "endpoint": "ifixitfast-service/getIncidents",
    "requestTransformOptions": {
      "sort": "{{ $page.variables.sortExpression }}",
    },
    "requestTransformFunctions": {
      "sort": "{{ $page.functions.sort }}"
    },
    "responseTransformFunctions": {
      "paginate": "{{ $page.functions.paginateResponse }}"
    }
  },
  "outcomes": {
    "success": "returnSuccessResponse",
    "failure": "returnFailureResponse"
  }
},
The corresponding module functions would be:
PageModule.prototype.sort = function (configuration, options) {
   /// some code here to modify 'configuration'
   return configuration;
}
 
 
PageModule.prototype.paginateResponse = function (configuration) {
   /// some code here to modify 'configuration'
   return configuration;
}