Use the C3 AI REST API in the C3 Agentic AI Platform
The REST Type can be mixed in to invoke third-party API calls. These Types define the API calls as standard methods on the Type, the same way you would define a function in a standard Type. All methods on a given REST Type can be executed against the same base URL, but specific endpoints can be defined.
Examples of Types that mix REST
Examples of Types that mix REST are Google and Jira.
Using the Google API
Google is an example of a Type that mixes the REST Type. Google Maps API uses API key authentication which can be configured as a secret value.
For more information about package structure, see Package Management Overview. See Access Control to learn about configuring authentication properties.
Configuration
The Google API key can be configured in multiple ways:
Use Google.Config directly
Google.Config.inst().setSecretValue("apiKey", <KEY>, <CONFIGOVERRIDE>)Use application-level method
Google.setApiKey(<KEY>)The Google.Config type mixes RestConfig to provide secure configuration management for the API key.
Type Definition
/**
* Google Rest endpoints wrapper
*
* The Google Maps API uses API key authentication.
* Configure the API key using Google.Config or Google.setApiKey() method.
*
* Usage:
* // Set API key
* Google.setApiKey(<KEY>)
*
* // Call geocode API
* // Calling the geocode method directly requires providing the api key query parameter directly since this is a REST method that directly calls the Google API. It is recommended to use the getLatLong method instead (see below)
* var rawResults = Google.geocode("1400 Seaport Blvd, Redwood City, CA 94063", "country:US|postal_code:94063", <API_KEY>)
*
* // If the API key has already been set, we can call `getLatLong` instead of `geocode`, which will internally call the `geocode` REST method with the correct API key
* var latLongResults = Google.getLatLong("1400 Seaport Blvd, Redwood City, CA 94063", "country:US|postal_code:94063")
*/
/**
* The Google type has a custom RestConfig type called Google.Config. If the base RestConfig type is enough for your REST type, you can just do `type TYPE_NAME mixes REST {` without the `<CONFIG_NAME>` after `REST`
*/
type Google mixes REST<Google.Config> {
/**
* Calls Google's geocode API with the supplied parameters
*/
@rest(uri='maps/api/geocode/json', method='GET')
geocode: abstract function(@rest(queryParameter=true)
address: !string,
@rest(queryParameter=true)
components: string,
@rest(queryParameter=true)
key: string): GoogleGeocodeResults
/**
* Calls Google's timezone API with the supplied parameters
*/
@rest(uri='maps/api/timezone/json', method='GET')
timezone: abstract function(@rest(queryParameter=true)
location: !string,
@rest(queryParameter=true)
timestamp: int,
@rest(queryParameter=true)
key: string): GoogleTimeZone
}In the example above, there are two APIs with different endpoints.
- The geocode function Rest endpoint is
https://<base url>/maps/api/geocode/json - The timezone function Rest endpoint is
https://<base url>/maps/api/timezone/json
Notice how both functions request the same base URL https://<base url>. For the Google type, the base URL is "https://maps.googleapis.com/" by default. The key parameter in each function is the API key used for authentication.
A Google Geocoding API request takes the following form: https://maps.googleapis.com/maps/api/geocode/json?address=<ADDRESS>&components=<COMPONENTS>&key=<API_KEY>
The uri in the @rest annotation indicates the output format is in JSON format.
When defining Types, annotations are used to configure the Types and the fields on them. Annotations are defined on the line above the Type, or the field, to which they apply. Add the annotation @rest(uri='maps/api/geocode/json', method='GET'). The method field in the @rest annotation indicates geocode is a GET request. Supported HTTP methods are GET, PUT, POST, and HEAD for the respective requests. If you need to include a parameter as part of the URI path, add the parameter and annotate it with partOfURI=true along with uriPrefix and uriSuffix as needed.
Refer to the topic on annotations for more information about annotations.
In both functions, notice there is a query parameter. Query parameters are a defined set of parameters appended to the end of the URL after the ? symbol. Query parameters are extensions of the URL and used to help define content or actions based on the data being passed.
The ! in front of string in the address parameter of the geocode function indicates the field is required and the value must be a string.
Using the Jira API
Unlike the Google Type, the Jira Type mixes multiple Types including the REST Type.
Unlike the previous example that contained a GET Http request, this example is a PUT request. You need to add data to the submit request. That is why the second parameter fields does not have the @rest(partofURI=true) annotation. The data you want to send over is not part of the REST endpoint.
type Jira mixes REST, JiraSoftwareMethods, DefaultInstance<Jira> {
/**
* Edit a Jira ticket
* You can NOT edit Status, Projects, and Comments with this method
* To edit the status of the issue, use transition function below.
* To add comments, use comment function below
*
* @param issueIdOrKey
* ID or key of the issue you want to edit. ID is a unique number.
* @param fields
* JiraIssueFields we want to edit
*/
@rest(uri='issue', method='PUT')
edit: abstract function(@rest(partOfURI=true, uriPrefix='/') issueIdOrKey: !string, fields: !JiraIssueFields)
}The REST Type handles calling the third-party APIs for you. You do not need to create and implement the function. Adding the keyword abstract in front of the function indicates this Type has additional custom methods that are not REST endpoints. For example, if you want to create a separate helper function to do some additional calculations or filtering but Jira does not provide this support.
Examples of Applications using REST types
The applications using REST Types should have the following structure (truncated for simplicity):
.
├── <package name>.c3pkg.json
├── rest
│└── config
│ ├── typeName/instanceName.json
└── src
└── packageName
├── typeName.c3typ
└── typeName.jsBelow are some examples of the config files and what they include:
Google JSON output
{
"url": "https://maps.googleapis.com/",
"retries": 3,
"maxConn": 1000,
"timeout": 3000
}Twilio JSON output
{
"retries": 3,
"maxConn": 1000,
"timeout": 300
}