Making an API Call
Once a client has a valid access token, use it to make requests to SAS Viya REST APIs.
The authenticated token is passed on requests to identify the caller. If a valid OAuth2 token is not provided on the call, the operation fails with a standard 401 Unauthorized response code. SAS REST APIs use the OAuth2 tokens to authorize specific REST API operations. For example, an authenticated user can have authorization to read a resource via a GET method, but not have authorization to update or delete a resource via a PUT or a DELETE methods.
The following call lists top level folders:
cURL
curl -k -X GET "https://<sas-server>/folders/folders/" \
-H "Accept: application/json" \
-H "Authorization: Bearer eyJhbGciOiJSUzI1NiIsImtpZ..."
Python
import requests
url = "http://<sas-server>/folders/folders/"
payload={}
headers = {"Accept": "application/json", "Authorization": "Bearer eyJhbGciOiJSUzI1NiIsImtpZ..."}
response = requests.request("GET", url, headers=headers, data=payload)
print(response.text)
Response
{
"links": [
{
"method": "GET",
"rel": "collection",
"href": "/folders/folders",
"uri": "/folders/folders",
"type": "application/vnd.sas.collection"
},
{
"method": "GET",
...
}
For more examples and information about making REST API calls, refer to this series of articles.
API Organization and Usage Information
The following sections provide information about the SAS Viya API organization, usage notes, and defines options when sending calls.
Collections
In SAS Viya REST APIs, collections are aggregations of zero or more resources. Most collections are represented as sets of resources rather than as ordered. Alternatively, you can think of collections as a map from resource IDs to a resource.
Most SAS Viya APIs manage collections of resources. For example, the Reports API
has a collection of report resources as a top-level resource, and the Files API
a collection of file resources as a top-level resource. Each collection is
identified with a URL that typically uses the plural form of the noun, such as
/reports/reports
or /files/files
. That means that in the URI
/reports/reports
, the first 'reports' is the namespace of the API and the
second 'reports' represents the name of the collection of reports.
Collection resources are represented with the application/vnd.sas.collection media type, which provides support for paginating, filtering, and sorting those collections. APIs are grouped for convenience into the following API categories:
API Category | Description |
---|---|
Automated Machine Learning | Automate machine learning capabilities |
CAS | Cloud Analytic Services API enables users to manageand perform CAS Actions |
Compute and Jobs | Act on SAS compute and analytic servers, including Cloud Analytic Services (CAS) |
Data Management | Enable data manipulation and data quality operations on data sources |
Fraud and Compliance | Proveds and entry point for ION messages to apply a decision on an incoming message |
Models and Decisions | Provide access to machine scoring and business rules |
Platform Administration | Provide operations for shared resources such as files and folders |
Visual Investigator | Enables users to execute and manage workflows created within SAS Visual Investigator |
Visualization and Reports | Provide access to reports and report images |
Filtering
SAS Viya APIs support filtering, which is a way to subset a collection to only those resources for which a provided Boolean condition is true. In this way, filtering is analogous to an SQL query with a WHERE clause. SAS REST APIs can support two forms of filtering: basic filtering and the use of a filter query parameter. If both are available, the two forms can be combined. Each individual API documents which filtering options are supported for that particular API.
Filtering is the application of a Boolean condition against a collection of resources in order to subset the collection to only those resources for which the condition is true. (For those familiar with SQL, filtering is analogous to a SQL query with a WHERE clause.) SAS REST APIs support two forms of filtering: basic filtering and a filter query parameter. The two forms can be combined.
Consider, for example, a collection of report resources. Given the following members:
Member | Type | Description |
---|---|---|
id | string | The report's unique identifier. |
name | string | The localizable report name. |
description | string | The localizable report description. |
createdBy | string | The name of the user who created this report. |
creationTimeStamp | date-time string | The date and time the report was first created. |
modifiedBy | string | The name of the last user who modified this report. |
modifiedTimeStamp | date-time string | The date and time the report was last modified. |
imageUris | object | The map of images of the report object. |
and this JSON representation of a report resource:
{
"id": "4eb3b675-e107-4857-a8f4-51aa555ac7e7",
"name": "Production Report",
"description": "Production forecasts by region and market segment.",
"createdBy": "dale",
"creationTimeStamp": "2017-04-19T14:54:04.705Z",
"modifiedBy": "dale",
"modifiedTimeStamp": "2017-04-19T14:55:11.643Z",
"links": [ ... ],
"imageUris": {
"icon": "/reports/icons/report.gif"
},
"version": 1
}
The filtering explanations below use this example scenario.
Basic Filtering
Basic filtering allows selecting resources by matching one or more members of
the resource to values passed as query parameters. For example, to find all
reports created by the user dale
, a basic filter is:
GET /reports/reports?createdBy=dale
The names of members in the resource representation (such as description
,
name
, createdBy
, modifiedBy
etc.) are used as the name of the
corresponding query parameters. The general form is
GET /reports/reports?memberName=value&...&memberName=value
Basic filtering supports only exact matches of members or simple set containment. Note that quotation marks are not used around either the names or the string values when using basic filtering.
Some APIs support nested resources, so you can use dot notation to select a
nested member, such as imageUris.icon
to filter based on the icon
member of
the imageUris
object in the above example resource.
When multiple basic query parameters are used, there is an implicit and
operation. That is, all the basic filter values must match in order for a
resource to be included in the response. For example, the request
GET /reports/reports?createdBy=dale&name=Production%20Report
returns reports that were created by dale
and that have the name
Production Report
. Note that the values must be URL encoded using standard
query parameter encoding rules; for example, a space in the value string has an
encoded value of %20
.
Some members are not well-suited to exact matching, such as the
modifiedTimeStamp
, which is a date-time value with sub-second precision:
?modifiedTimeStamp=2017-04-19T14:55:11.643Z
. For such requirements, you should
use the filter parameter described below to select resources based on ranges,
comparisons, and other selection criteria.
Basic Set Containment Filtering
When using basic filtering, you can pass a pipe-separated set of values. The basic filter matches if the named member matches any of the values in the set. As with simple query parameters, do not use quotation marks around the values.
For example, to find reports created by users dale
or elaine
or jules
, use
the pipe-separated set containment notation to express the set of values, such
as dale|elaine|jules
. Of course, the | character must be URL-encoded as %7C
when using set containment notation in a query parameter. That means:
GET /reports/reports?createdBy=dale|elaine|jules
is URL encoded as:
GET /reports/reports?createdBy=dale%7Celaine%7Cjules
The values must be URL encoded as well.
Filtering with the 'filter' Query Parameter
The filter query parameter provides a flexible way to subset the resources from collections by combining comparison and other functions.
?filter=filterExpression
Unlike basic filtering, the filterExpression enables you to:
- combine multiple expressions with logical operations (and, or, and, not)
- make comparisons using relational operators (
eq
,ne
,lt
,le
,gt
,ge
) - use other functions such as
contains
,startsWith
,in
,match
, and so on
The simple (and somewhat useless) filter ?filter=true
evaluates to true for
all items in the collection — this is the default behavior if no filter is
provided.
The filter
query parameter names a filter expression, which uses a very simple
expression notation. The filter expression syntax expresses the same condition
as a combination of function calls:
and(or(e,not(b)),gt(C,0))
Parentheses surround the comma-separated arguments to each function and are required to differentiate a function from a member name. Figure 1 shows the structure of the expression; ovals represent functions or operations and rectangle represent members or literal values.
Filter Expression Syntax
The syntax for filter expressions:
expression := literal |
expression := name |
expression := function |
function := identifier '(' [ arguments ] ')' |
arguments := expression [ ',' arguments ] |
literal := 'true' | 'false' |
literal := number |
literal := date |
literal := time |
literal := date-time |
literal := string |
string := "'" characters "'" |
string := '"' characters '"' |
name := identifier [ '.' name ] |
Consult the documentation for each API to determine the default limit for its paginated collections.
For example, the basic query used above,
GET /reports/reports?createdBy=dale&name=Production%20Report
can be expressed by combining two equality test functions on the members
createdBy
and name
, combined with the and
function:
GET /reports/reports?filter=and(eq(createdBy,'dale'),eq(name,'Production%20Report'))
Filter Expressions
There are three types of expressions that can be used in the filterExpression a filter query: literals, names, and functions.
Filter Literals
Literals (also known as constants) are fixed values, such as
the string 'dale' |
the string 'Production Report' |
Boolean literals true and false |
numbers such as 100 or -5.75 date, time, and date-time literals |
Literals are typically used as arguments to functions.
String literals are sequences of zero or more characters enclosed in quotation marks. In filter query parameters, strings can be enclosed in either single or double quotes. The string literal 'dale' is the same as the string literal "dale"; only the contents of the string is significant. If the string contains quote characters, use one of two representations:
To include single quotes (') in a string literal, use double quotes to quote the string: "Dale Smith's ID is 'dale'". To include double quotes (") in a string literal, use single quotes to quote the string: 'Dale chose the ID "dale".'.
Alternatively, you can uniformly double each embedded quote character:
'IT assigned the user ID ''dale'' to Dale Smith.' "IT assigned the user ID 'dale' to Dale Smith."
are identical and have the value:
IT assigned the user ID 'dale' to Dale Smith.
Names
Names in filter expressions refer to members of the items in the collection,
such as the members name
, createdBy
, modifiedBy
, or imageUris.icon
from
the example report resource above. Names are typically used as arguments to
functions, such as comparing the members to literal values, as described below.
An example is the expression
eq(createdBy,'dale')
which is true for any item in the collection that has the exact value 'dale' as
its createdBy
member.
Date, time, and date-time literals are other name filters.
- A
date
literal uses the form yyyy-MM-dd such as 2017-07-27. - A time literal uses the form HH:mm:ss and HH:mm:ss.SSSZ where the hours HH range from 00 to 24 and the fractional seconds and time zone are optional. The time zone code Z means UTC (GMT) time zone. Time zone offsets if +HH:mm and -HH:mm are also allowed instead of Z.
- A
date-time
literal uses the form yyyy-MM-ddTHH:mm:ss.SSSZ where the fractional seconds and time zone are optional; for example, 2017-06-28T03:18:53.0717Z
Note: date, time, and date-time values are not quoted as strings.
Filter Function Expressions
Functions operate on one or more values, which form the arguments to the function. A function expression has the form:
function := identifier '(' [ arguments ] ')'
arguments := expression [ ',' arguments ]
such as eq(name,'dale')
. Here, the function name is eq
and the two function
arguments (a name and a string literal) are encoded in parentheses and separated
by commas.
Below is the base set of functions that can be used in filter expressions.
Logical Functions
Logical functions combine other Boolean expressions.
Expression | Rule |
---|---|
and(e0, e1 [,..., en]) | true if and only if all expressions are true; at least two expressions required. This uses short-circuit semantics (does not evaluate remaining ei, ..., e expressions arguments if ei is false). |
or(e0, e1, [... en]) | true if and only if one or more expressions are true; at least two expressions required. or uses short-circuit semantics (does not evaluate remaining expressions if any ei is true). |
not(e) | true if and only if expression e is false |
isNull(e) | true if and only if e is null or unset |
Relational Functions
Relational functions compare two or more expressions. Most functions accept two or more arguments, in which case the relation must hold for consecutive values. In other words, lt(a,b,c,d) is equivalent to and(lt(a,b),lt(b,c),lt(c,d)) (that is, a < b && b < c && c < d.
This syntax cannot express combinations of relational operators, such as minInclusive ≤ x < maxExclusive; one must use and(le(minInclusive,x),lt(x,maxExclusive)).
Expression | Rule |
---|---|
eq(e0, e1 [,..., en]) | true if and only if all expressions are equal. |
ne(e0, e1) | true if and only if the e0 is not equal to e1 |
lt(e0, e1 [,..., en]) | true if and only if each expression ei is less than ei+1 |
le(e0, e1 [,..., en]) | true if and only if each expression ei is less than or equal to ei+1 |
gt(e0, e1 [,..., en]) | true if and only if each expression ei is greater than ei+1 |
ge(e0, e1 [,..., en]) | true if and only if each expression ei is greater than or equal to ei+1 |
in(e, v0, v1 [,..., vn]) | Set containment, true if and only if the value e is equal to at least one of the vi values. |
Relational functions can be combined with date, time, and date-time literals. To find all reports created between January and March 2017 (using GMT).
GET /reports/reports?filter=le(2017-01-01T00:00:00Z,creationTimeStamp,2017-03-31T24:00:00Z)
String Functions
Functions that manipulate string values.
Expression | Rule |
---|---|
match(e,regularExpression) | true if and only if the string e matches a regular expression. The regularExpression is a quoted string literal or other expression that yields a string pattern. |
matchAll(regularExpression, exp1,...,expn) | true if all expressions match the regular expression. Uses short-circuit semantics (do not evaluate remaining expressions if any preceding expression does not match). |
matchAny(regularExpression, exp1,...,expn) | true if any expressions match the regular expression. |
match(map,name,regularExpression) | true if and only if the member map is a Map or Properties object, which contains an item (key,value) such that and(match(key,name),match(value,regularExpression) is true |
contains(e,substring) | true if and only if the string e contains the substring, or if e is a list/set/collection, true if and only if an element of e equals substring |
startsWith(e,prefix) | true if and only if the string e starts with prefix |
endsWith(e,suffix) | true if and only if the string e ends with the suffix |
blank(e) | true if and only if the string a consists of only whitespace |
length(e) | the integer length of the string expression e |
substr(e,start,len) | the substring of e, starting at start (zero-based index?) and including len chars. Negative index start counts backward from the end. If len is omitted, the substring will extend to the end of the string. |
upCase(s) | convert all character in s to uppercase. |
downCase(s) | convert all character in s to lowercase. |
Locale-sensitive Collation
Several of the above functions require locale-sensitive collation, where the locale is derived by the Accept-Language header passed by the client.
Locale-sensitive collation strength is passed to these functions using one of several reserved identifiers, as optional first arguments. The identifier name is obtained by prefixing the collation options below with a dollar sign ('$'):
Locale-sensitive collation | Description |
---|---|
$primary | normal case-insensitive comparison |
$secondary | only different accent characters are significant |
$tertiary | normal case-sensitive comparison |
$quaternary | punctuation is considered |
$identical | case, accents, and punctuation differences are significant |
If the first parameter is not one of these special identifiers, the default is $identical. These reserved identifiers are ignored when comparing numeric and Boolean values.
Examples of locale-sensitive functions, using $tertiary as an example:
Expression |
---|
eq($tertiary, a, b,...) |
(equal) ne($tertiary, a, b) (not equal) |
lt($tertiary, a, b,...) (less than) |
le($tertiary, a, b,...) (less than or equal) |
gt($tertiary, a, b,...) (greater |
than) ge($tertiary, a, b,...) (greater than or equal) |
in($tertiary, e, v0, v1 |
[,..., vn]) contains($tertiary, e, substring) |
startsWith($tertiary, e, prefix) |
endsWith($tertiary, e, suffix) |
Combining Basic Filtering and the Filter Query Parameter
An API request can combine basic filtering and the filter query parameter.
When both are used, the request combines them by adding an implicit and
function to the existing filter
query parameter. For example, for
GET .../resource?name=dale&format=ruled&filter=or(bounded,lt(shipDate,2017-07-27))
The basic filters (name=dale and format=ruled
) will be merged into the filter
expression, or(bounded,lt(shipDate,2017-07-27))
, yielding the effective filter
query
GET .../resource?filter=and(eq(name,'dale'),eq(format,'ruled'),or(bounded,lt(shipDate,2017-07-27)))
Note that the resulting filter expression is always false if the basic filter and the filter specify mutually exclusive values:
GET .../resource?name=dale&format=ruled&filter=eq(name,'jack')
The effective filter query:
GET .../resource?filter=and(eq(name,'dale'),eq(format,'ruled'),eq(name,'robert')
This is always false (resulting in an empty collection result) because name cannot be 'dale' and 'robert' at the same time.
Sorting
When making a request for a collection or applying a query on its subsetting, a client often requires that the response data is returned in a sorted order.
Sort criteria are specified by the sortBy
query parameter.
GET https://www.example.com/reports/reports?sortBy=name,description
This API request results in a paginated collection view that is sorted -- first by the report name, then by the description.
The value of the sortBy
parameter is one or more sort criteria, separated by
commas. Sort criteria must include one or more keys that match the members of a
resource. Each sort criteria can also have sort options, which specify sort
order or collation strength.
Note: Not all APIs support collation strength options. In those cases, values
specified in the sortBy
parameter are not honored by the underlying service.
When invoking a query on an orderable collection, the client often requires the data in a sorted order for presentation to the user. Sort criteria are specified by the sortBy query parameter.
GET https://www.example.com/reports/reports?sortBy=name,description
This call results in a paginated collection view that is sorted first by the report name, then by the description.
The value of the sortBy
parameter is one or more sort criteria, separated by
commas. Sort criteria consist of a key, which is a member of a resource. Each
sort criteria can also have sort options, which specify sort order or collation
strength. Note: Not all APIs support collation strength options. (The values can
be specified in the sortBy
parameter but are not honored by the underlying
service.)
sortBy Syntax
The syntax of the sortBy
criteria is defined by the following
Backus–Naur form
syntax:
sortCriteria ::= criteria [ ',' sortCriteria ]
criteria ::= key [ ':' options ]
options ::= option [ ':' options ]
option ::= 'ascending' | 'descending'
option ::= 'primary' | 'secondary' | 'tertiary' | 'quaternary' | 'identical'
The key is the name of a member (also known as a field) in the resources
that are being sorted. For example, if a collection resource /someApi/models
contains a collection of models, and each model has members with names model
,
type
, modifiedTimeStamp
and modifiedBy
, a client can request the
collection of models sorted first by modified date (most recent first), then who
last modified the resource, then by type, then by name:
GET https://www.example.com/someApi/models?sortBy=modifiedTimeStamp:descending,modifiedBy,type,name
If more than one criteria exist, they are considered subgroup sorting criteria. The order is important: the second sort criteria, if present, applies to items that are equal according to the first sort criteria, and so on. It is unlikely that many resources will have the same modifiedTimeStamp. For the query
GET https://www.example.com/someApi/models?sortBy=modifiedBy,type,modifiedTimeStamp:descending
there are likely to be several models modified by each user, and for each user, several models with the same type. Within those subgroups, the items are sorted by descending modified timestamp.
sortBy Criteria Options
Ordering options are:
Option | Description |
---|---|
ascending | sort in ascending order; this is the default order default if descending is omitted |
descending | sort in descending order |
primary | Typically, this is used to denote differences between base characters (for example, "a" < "b", "a" == "A"). It is the strongest difference. For example, dictionaries are divided into different sections by base character. Case is ignored. |
secondary | Accents in the characters are considered differences (for example, "as" < "às" < "at", , "at" == "At"). Other differences between letters can also be considered secondary differences, depending on the language. A secondary difference is ignored when there is a primary difference anywhere in the strings. Case is ignored. |
tertiary | Uppercase and lowercase differences in characters are distinguished at tertiary strength (for example, "ao" < "Ao" < "aò"). In addition, a variant of a letter differs from the base form on the tertiary strength (such as "A" and "Ⓐ"). Another example is the difference between large and small Kana. A tertiary difference is ignored when there is a primary or secondary difference anywhere in the strings. |
quaternary | When punctuation is ignored at primary to tertiary strength, an additional strength level can be used to distinguish words with and without punctuation (for example, "ab" < "a-b" < "aB"). |
identical | When all other strengths are equal, the identical strength is used as a tiebreaker. The Unicode code point values of the NFD form of each string are compared, just in case there is no difference. For example, Hebrew cantillation marks are distinguished only at strength. This strength should be used sparingly, as only code point value differences between two strings is an extremely rare occurrence. Using this strength substantially decreases the performance for both comparison and collation key generation APIs. |
If you want case-sensitive comparison, use tertiary
. For case-insensitive
comparison, use either primary
or secondary
; for example, depending on
whether you want á to be grouped with â.
If more than one of {ascending
,descending
} appear, the last occurrence is
used. If more than one of {primary
,secondary
,tertiary
,identical
} appear,
the last occurrence is used. The default sorting strength is tertiary
.
Consult the documentation for each API to determine the default sort order for
its orderable collections. If it is not documented, you can assume that the
collection order is not guaranteed and the service might return items in a
different order in future requests. For pagination, the first
, next
, prev
,
and last
link relations, if present, preserve the sortBy
query parameter if
it was used. For pagination, the start
query parameters are relative to sorted
collection indexes.
The sort keys are selected from the full set of fields in the collection's underlying resource, which can be a superset of the fields in the requested representation on any specific query.
Links
SAS Viya REST APIs follow REST conventions including links in REST responses.
Just like an HTML page can include links that connect the page to related pages,
links in REST responses connect the resources of the API to operations available
for that resource or to related resources. Here is an example of using the
Reports API to retrieve a report:
GET http://www.example.com/reports/reports/4ebf1327-c72b-4857-a8f4-421a555ac7e7
The response includes a set of links, such as the following:
{
"id": "4ebf1327-c72b-4857-a8f4-421a555ac7e7",
"name": "monthly-sales-analysis",
"description": "Monthly sales analysis report",
....,
"links": [{
"method": "GET",
"rel": "self",
"href": "/reports/reports/4ebf1327-c72b-4857-a8f4-421a555ac7e7",
"uri": "/reports/reports/4ebf1327-c72b-4857-a8f4-421a555ac7e7",
"type": "application/vnd.sas.report"},
{
"method": "PUT",
"rel": "update",
"href": "/reports/reports/4ebf1327-c72b-4857-a8f4-421a555ac7e7",
"uri": "/reports/reports/4ebf1327-c72b-4857-a8f4-421a555ac7e7",
"type": "application/vnd.sas.report",
"responseType": "application/vnd.sas.report"},
{
"method": "DELETE",
"rel": "delete",
"href": "/reports/reports/4ebf1327-c72b-4857-a8f4-421a555ac7e7",
"uri": "/reports/reports/4ebf1327-c72b-4857-a8f4-421a555ac7e7"},
{
"method": "GET",
"rel": "content",
"href": "/reports/reports/4ebf1327-c72b-4857-a8f4-421a555ac7e7/content",
"uri": "/reports/reports/4ebf1327-c72b-4857-a8f4-421a555ac7e7/content",
"type": "application/vnd.sas.report.content"}
],
....
}
The returned links indicate actions, operations, or state transitions that the client can make from the current resource or related resources. In the example above, the links with the "rel" values of "update" and "delete" indicate state transitions available from the current resource. Specifically, the links define operations to update or delete the report.
Links can also represent an object's relationships to other resources. For example, the link with the value "content" for the "rel" member in the above example (called "the content link") associates the report with the report's content.
Pagination
Many collections in SAS Viya APIs can contain very large numbers of resources, and it is not useful or reasonable to request all of them at once. Instead, most collections return pages of items, where each page represents reasonably sized, consecutive subsets of the full collection. Each page can also contain links to other pages, such as the first and last page, or the previous and next page. Pagination can also be combined with sorting and filtering.
Pagination Query Parameters
For collections, APIs use start and limit query parameters to fetch (GET)
subsets of collections. Given that a client application might only be displayed
or operate on a small subset of the collection, the pagination query parameters
prevent transmission of entire, large collections across networks. Consider the
following:
GET https://www.example.com/''collection''?start=item-index&limit=max-item-count
GET https://www.example.com/''collection''?start=item-index
GET https://www.example.com/''collection''?limit=max-item-count
Parameter | Description |
---|---|
start | Start is a zero-based integer index (the first item is index == 0) The default start is 0, or item-index. |
limit | An integer that specifies the maximum number of items to return in the response. |
Consult the documentation for each API to determine the default limit for its paginated collections.
Pagination Links
Collection results return hypermedia controls that can include the following links:
Parameter | Description |
---|---|
first ("rel" : "first") | A link to the first page in the collection (?start=0). |
previous ("rel" : "prev") | A link to the previous page in the collection, if there is one. |
next ("rel" : "next") | A link to the next page in the collection, if there is one. |
last ("rel" : "last") | A link to the last page in the collection. |
self ("rel" : "self") | A link to the current page in the collection, using the same filter and sort criteria |
Conditional Operations
SAS Viya REST APIs can use conditional operations as defined with HTTP/1.1. Conditional operations support many concurrent reads of resources, and accepts updates to those resources if request satisfies a precondition. Preconditions are expressed with request headers to ensure that the update request (such as a PUT or PATCH and perhaps a POST) is based on the current state of the resource being updated.
Note that not all SAS Viya APIs support preconditions. SAS APIs use preconditions in operations where concurrent updates are likely. These SAS APIs use either entity tags or last-modified timestamps to satisfy update preconditions.
Entity Tags
An entity tag is an opaque string that marks (or "tags") the current state of a
resource. The entity tag changes each time the resource is updated and are
returned in the ETag
response headers from supporting operations.
SAS APIs that use entity tags must pass the If-Match
request header using the
value of the entity tag received from the latest operation on the resource. This
acts as a precondition: the update operation fails if the value of the
If-Match
header on the request does not match the current entity tag of the
resource. A precondition failure means that a client has stale data and the
resource has been updated since the current client last obtained the entity tag.
Clients can simply make a GET request to the resource to obtain a new entity
tag, and then retry the operation if appropriate.
Last-Modified Timestamps
APIs that use a Last-Modified
timestamp return a timestamp that changes each
time a resource is updated. Preconditions based on "last-modified" return a
Last-Modified
response header. Resources expect a If-Unmodified-Since
precondition request header with the timestamp value based on the previous
Last-Modified
timestamp. Timestamps use the format
EEE, dd MMM yyyy HH:mm:ss GMT
, such as Thu, 13 Sep 2016 07:27:08 GMT
.
Precondition Status Codes
SAS Viya APIs return standard precondition HTTP status codes:
Code | Status | Description |
---|---|---|
412 | Precondition Failed | Returned if an API operation specifies preconditions and the precondition is not satisfied |
428 | Precondition Required | Returned if an operation requires preconditions but the client does not pass the required preconditions request headers |
Precondition failures occur when a client has stale data and the resource has
been updated since the current client last obtained the entity tag. Clients can
simply make a GET
request to the resource to obtain a new entity tag, and then
retry the operation if appropriate.
Note that if an operation accepts and is passed both If-Match
and
If-Unmodified-Since
preconditions, only the If-Match
precondition is checked
and If-Unmodified-Since
is ignored.