Web APIs

Overview

Web APIs provide a way to expose Appian data and services to outside systems. Each Web API is an association between a URL/HTTP method combination and an expression. When a client makes an HTTP request to the given URL, the associated expression is executed and the result is returned to the client. This means that any data or service that is available inside an expression can be exposed to an external system via a Web API.

Some things you might choose to expose with a Web API include:

  • A list of tasks for a specified user
  • A list of records for a specific record type
  • Data about a specific record, similar to a record dashboard
  • The ability to write to a data store
  • The ability to start a new instance of a process model

Invoking a Web API

Authentication

Web APIs use the same authentication mechanism that the rest of Appian uses. This means that in the standard out-of-the-box configuration there are two different ways to authenticate with Appian in order to call a Web API:

  • Standard forms-based login
  • HTTP basic authentication

You can add to or modify these options by configuring the authentication for your site.

If you are invoking an Appian Web API from a user's browser (for instance to populate a task list for use with an embedded interface), we recommend setting up SSO between Appian and the site that will initiate the call to the Web API.

If you wish to invoke an Appian Web API from another system, you must use HTTP basic authentication. HTTP basic authentication for Appian Web APIs requires preemptive authentication as unauthorized requests will not prompt clients for credentials with a 401 status code.

As a reminder, you should never store passwords for connecting to Appian in plaintext.

Cross-Origin Requests

HTTP requests made by one web site to another are said to be "cross-origin" because the origin (the url) of the first web site is different than the origin of the other site. Web browsers block requests of this nature by default for security reasons. However, web sites that wish to opt into allowing other sites to access their resources can use a standard called "Cross-Origin Resource Sharing", or CORS, to mark resources as being shareable with other sites. To configure this in Appian, you must add any sites you wish to expose data or services to in this manner to the allowed origins list in the Appian Administration Console.

For POST, PUT, and DELETE Web APIs, adding a web site to the allowed origins list will also exempt that site from Appian's built-in cross-site request forgery (CSRF) protection. You should not add sites that you don't trust to the allowed origins list.

HTTP Methods

When creating or editing a Web API, designers can select from one of the following HTTP methods: GET, POST, PUT, and DELETE. Additionally, the HTTP methods OPTIONS and HEAD are automatically handled by the system based on the Web APIs that exist in the system for a given Endpoint.

HEAD requests will execute the Web API for the GET method for the Endpoint and return the result, minus the response body.

OPTIONS requests will return a list of methods for which Web APIs exist for a given Endpoint.

For example, assuming that you have two Web APIs with the Endpoint field set to customer, one for GET and one for POST, and you make an OPTIONS request to https://www.example.com/suite/webapi/customer, the response will looks something like the following.

HTTP/1.1 200 OK
Date: Tue, 19 Apr 2016 15:27:22 GMT
Server: Apache
Pragma: No-cache
Cache-Control: no-cache
Expires: Thu, 01 Jan 1970 00:00:00 GMT
X-Frame-Options: SAMEORIGIN
Allow: GET, POST, OPTIONS
Content-Length: 0
Keep-Alive: timeout=20, max=100
Connection: Keep-Alive
Content-Type: text/plain

Note that the Allow header contains entries for both GET and POST.

Only Web APIs for the POST, PUT, and DELETE methods may execute smart services. Web APIs for the GET method will not execute any smart services included in their expression. Attempting to do so will result in the following error message: Smart Services cannot be executed in Web APIs that have a method of "GET."

HTTP Status Codes

There are several factors that affect what HTTP status code a Web API returns.

Status Code Condition
404 There is no Web API with the specified endpoint and HTTP method
404 The user is not in the viewer role or higher for the Web API
500 There was an error evaluating the Web API's expression
500 The result of the expression evaluation was not an HTTP Response object

Additionally, designers may specify in their expression a status code that the Web API should return. This allows them to do things like return a 404 code if data about a record that does not exist is requested.

Designing a Web API

Creating a Web API

  1. Open the Appian Designer.
  2. Create a new application or open an existing one.
  3. Select New > Web API. This opens the Create Web API form.
  4. Enter a name for the Web API. This name is displayed only to Appian designers.
  5. Select an HTTP method.
  6. Enter an endpoint for the Web API. This is used as part of the Web API's URL to identify it and will be seen by end users and in log files for network devices and servers.
    • The combination of the HTTP method and endpoint must be unique across all Web APIs in the system.
  7. Click Create & Edit. This opens the Web API designer.

Templates

When you first open the Web API Designer and the Web API doesn't already have an expression defined, the first thing that you will see is a dialog with a selection of templates that you can pick from. These templates are intended to give you a starting point from which you can quickly build out your Web API.

Selecting one of the templates will populate your Web API with an example expression and test inputs and convert it to use the proper HTTP method for that expression.

You'll notice that each template expression returns an HTTP Response object, built with a!httpResponse(). All Web APIs must return an HTTP Response.

Executing a Smart Service

Web APIs that use the POST, PUT, or DELETE HTTP methods are able to execute a smart service.

Every smart service that can run inside a Web API has an onSuccess and an onFailure parameter that expects an HTTP response defined using a!httpResponse(). When the smart service executes successfully, the HTTP response defined in the onSuccess parameter is returned. When the smart service encounters an error and is unable to execute, the HTTP response defined in the onError parameter is returned.

The example below uses the Write to Data Store Entity smart service. When the write is successful the Web API results in an HTTP response with a 200 status code and a body containing the JSON-encoded data that was written to the data store. When the write is unsuccessful, the Web API results in an HTTP response with a status code of 500 and a body containing a JSON-encoded error message.

a!writeToDataStoreEntity(
  dataStoreEntity: cons!EMPLOYEE_ENTITY,
  valueToStore: type!Employee(
    firstName: http!request.queryParameters.firstName,
    lastName: http!request.queryParameters.laseName,
    department: http!request.queryParameters.department,
    title: http!request.queryParameters.title
  ),
  onSuccess: a!httpResponse(
    statusCode: 200,
    headers: {
      a!httpHeader(name: "Content-Type", value: "application/json")
    },
    body: a!toJson(
      fv!storedValues
    )
  ),
  onError: a!httpResponse(
    statusCode: 500,
    headers: {
      a!httpHeader(name: "Content-Type", value: "application/json")
    },
    body: a!toJson(
      {
        error: "There was an error writing to the data store"
      }
    )
  )
)

Accessing The HTTP Request

Data from the incoming HTTP request is exposed to the expression in the variable http!request. This variable is a dictionary that contains the following fields:

Field Type Description
url Text The URL of the incoming request, including protocol, hostname, port, path, and query parameters
pathSegments List of Text A list of text where each item in the list corresponds to a segment of the URL from the incoming request separated by /s. The first item in the list will be the section of the URL that immediately follows the endpoint.
queryParameters Dictionary A dictionary where the keys are the names of the query parameters from the request and the values are the values of those parameters
headers Dictionary A dictionary where the keys are the names of the headers from the request and the values are the values of those headers
body Text The body of the incoming request
formData Dictionary An alternate representation of the request body that is a dictionary where the keys are the names of the fields from the body of the request and the values are the values of those fields. This is only available when the the incoming request contains a Content-Type header with a value of application/x-www-form-urlencoded and the contents of the request body can be parsed as that content type.

Example: GET Requests

If a user makes a GET request to https://www.example.com/suite/webapi/customer?customerId=5 the value of http!request will be the following:

Field Value
url https://www.example.com/suite/webapi/customer?customerId=5
pathSegments {}
queryParameters {customerId: "5"}
headers {}
body ""

In the above example, you can extract the value of the customer ID from the request using the expression http!request.queryParameters.customerId.

Expression Value
http!request.queryParameters.customerId "5"

However, if the user instead makes a GET request to https://www.example.com/suite/webapi/customer/5 with no headers the value of http!request will be the following:

Field Value
url https://www.example.com/suite/webapi/customer/5
pathSegments {"5"}
queryParameters {}
headers {}
body ""

In the above example, you can extract the value of the customer ID from the request using the expression http!request.pathSegments[1].

Expression Result Value
http!request.pathSegments[1] "5"

Note that in both examples above, the ID of the customer was of type Text, not Number. This is because all HTTP URLs, including path and query parameters, are fundamentally text and not numbers. All values in the http!request.queryParameters and http!request.headers dictionaries are of type Text.

Example: POST Requests

For POST requests, the body of the request is exposed in two fields: body and formData.

If a user makes a POST request to https://www.example.com/suite/webapi/customer where the body of the request contains id=7&name=Acme+Corporation&firstPurchaseDate=2016-03-12 and there a content type header with a value of application/x-www-form-urlencoded, the value of http!request will be the following:

Field Value
url https://www.example.com/suite/webapi/customer/
pathSegments {}
queryParameters {}
headers {Content-Type: "application/x-www-form-urlencoded"}
body "id=7&name=Acme+Corporation&firstPurchaseDate=2016-03-12"
formData {id:"7", name:"Acme Corporation", firstPurchaseDate:"2016-03-12"}

If the same request did not contain a content type header or if it had a value other than application/x-www-form-urlencoded, the formData field of http!request would have been null.

When designing a Web API, you can save a default value for your test HTTP request using the Set as default test values link in the Web API designer. Once set, the default values will be saved with the interface.

Versions

Versioning for Web APIs is very similar to versioning for rules. All versions of a Web API are saved and designers can view the definitions of old versions, but when a user invokes a Web API it is always the current version that executes. There is no way for a user to invoke a previous version of a Web API.

In order to access previous versions of your Web API, select Versions in the Settings gear menu.

This option will open the Versions dialog, which displays basic information about all other versions of the Web API and includes a link to each version. The version description is also shown here and can act as designer notes for descriptions that are not exposed to end users.

If you wish to revert your Web API to this older version, click the Save button. This will save a new version of the Web API with the definition that is currently loaded in the designer. Modifying a previous version and saving it as the latest version does not affect the old version.

Security

Each Web API has a rolemap that specifies its viewers, auditors, editors, and administrators.

The rights for each role are described in the following table.

Actions / Roles Administrator Editor Auditor Viewer
Execute Yes Yes Yes Yes
View the configuration Yes Yes Yes Yes
View the security Yes Yes Yes No
Update the configuration Yes Yes No No
Update the security Yes No No No
Delete Yes No No No

To access the Web API object's definition and rolemap, users must also be in the designer role.

The Administrator user may view, edit, and delete Web APIs but may not execute them. This includes testing them inside the Web API Designer.

Logging

If there is an error executing the expression associated with a Web API, the error message appears in logs/design_errors.csv rather than in the standard application server error log.

See also: Web API Performance Logs and Web API Metrics Logs

Web API Performance

The performance view shows you detailed performance information for your web API. This allows you to identify and address performance bottlenecks and to understand the impact of particular rules and functions.

The performance view can be accessed using the Performance View option in the gear menu in the header. See the Performance View page for more information on how to use the performance view.

FEEDBACK