APL Data Sources
A data source is a JSON structure that defines data you can bind to an APL document. When you send an APL document to Alexa with the RenderDocument
directive, you can include one or more data sources. You bind the data sources by including them in the parameters of the APL document. You can then use a data-binding expression to bind the data to component properties within the document.
- Send a data source in the RenderDocument directive
- Bind the data source to the document
- Typed and untyped data sources
- object data source
- dynamicIndexList data source
- Related topics
Send a data source in the RenderDocument directive
Pass a data source to Alexa in an optional datasources
object that is part of the RenderDocument
directive, but outside of the APL document itself. This datasources
object contains an object representing each data source.
This example shows a skill response with the RenderDocument
directive. It passes the document and a data source named "myDocumentData". The document content is omitted for brevity:
{
"version": "1.0",
"response": {
"outputSpeech": {
"type": "SSML",
"ssml": "<speak>This is a sample</speak>"
},
"sessionAttributes": {},
"directives": [
{
"type": "Alexa.Presentation.APL.RenderDocument",
"token": "[SkillProvidedToken]",
"document": {
"type": "APL",
"version": "1.5",
"mainTemplate": {
"parameters": [
"myDocumentData"
],
"items": []
}
},
"datasources": {
"myDocumentData": {
"title": "This is a very simple sample"
}
}
}
]
}
}
Bind the data source to the document
Use data-binding expressions to bind data in the data source to component properties in your APL document.
To bind data in a data source to component properties in your document
- Declare a parameter in the
mainTemplate.parameters
array that matches the key for the data source object. - In the component properties, refer to the data source properties with the syntax
${dataSourceName.propertyName}
wheredataSourceName
is the same key you used inmainTemplate.parameters
.
For example, assume you have the following data source object:
{
"myDocumentData": {
"title": "This is a very simple sample"
}
}
The key for this data source is myDocumentData
. Declare the parameter myDocumentData
in mainTemplate.parameters
:
{
"type": "APL",
"version": "1.5",
"mainTemplate": {
"parameters": [
"myDocumentData"
],
"items": []
}
}
Finally, use a data-binding expression to bind a component property to the data in myDocumentData
. Use the myDocumentData
key to access the properties. For example, this expression resolves to the value "This is a very simple sample": ${myDocumentData.title}
.
The following example shows an APL document that displays the content from the myDocumentData.title
property in a text component.
{
"type": "APL",
"version": "1.5",
"import": [
{
"name": "alexa-layouts",
"version": "1.2.0"
}
],
"mainTemplate": {
"parameters": [
"myDocumentData"
],
"items": [
{
"type": "Container",
"width": "100vw",
"height": "100vh",
"items": [
{
"type": "Text",
"text": "${myDocumentData.title}"
}
]
}
]
}
}
About binding a data source to payload or other parameters
In versions of APL before 1.3, you could not use the key for your data source as the parameter in mainTemplate.parameters
. Instead, you set the parameter to a string like "payload". The "payload" parameter was then mapped to the entire datasources
object provided in your skill response. Your data-binding expressions then had to include this parameter. For example, an expression to get the title
property from the earlier example would be ${payload.myDocumentData.title}
.
Documents that use "payload" as the mainTemplate.parameters
do continue to work. However, the simplified form is recommended for new APL documents. Note that using other strings as the parameter does not work. You must use either "payload" or the data source key.
Typed and untyped data sources
A data source can be untyped or typed.
- Untyped – A JSON object with an arbitrary set of properties you define. The
myDocumentData
example shown earlier is an example of an untyped data source. - Typed – A JSON object with a structure defined by the Alexa Skills Kit. You must use typed data sources for some functionality. APL supports two typed data sources
object
– Required to use transformers to manipulate the data, such as converting SSML text to speech or creating a hint that includes the configured wake word for a device.dynamicIndexList
– Required to use lazy loading to load data progressively as the user scrolls and for modifying the data source after the document is rendered.
object data source
The object
data source type adds properties required for transformers. You use transformers to manipulate the data. For example, you use a transformer to put wake word of the user's device into a hint string.
The object
data source has the following properties:
Property | Type | Required | Description |
---|---|---|---|
type | object | Yes | Must be "object". |
properties | object | No | An object containing properties that you can use with transformers. The transformers always expect to find data in the properties object. You define the structure of the data within properties |
objectID | String | No | An optional identifier for an object data source. |
description | String | No | Optional description of the data source. |
transformers | Array | No | An array of transformers to apply to values in the properties object. |
An object
data source can also include other arbitrary properties that you can bind to your document as needed.
This example shows an object
data source with data in both the properties
object and an arbitrary property (hello
). The data source also has the textToSpeech
transformer. The transformer references data within the properties
object. For more about how to use transformers, see Transformers.
{
"myDocumentData": {
"type": "object",
"properties": {
"title": "This is another very simple sample.",
"mainText": "Note these properties are in a <code>properties</code> object."
},
"hello": "Hello, World!"
"transformers": [
{
"inputPath": "title",
"outputName": "titleSpeech",
"transformer": "textToSpeech"
}
]
}
}
dynamicIndexList data source
The dynamicIndexList
data source adds properties required for lazy loading and dynamic data sources. With lazy loading, Alexa displays large lists progressively as the user scrolls through the content. With dynamic data sources, you can update the data source after sending it to Alexa, so you can change the values on the screen without sending an entirely new document.
The dynamicIndexList
data source has the following properties:
Property | Type | Required | Description |
---|---|---|---|
type | String | Yes | "dynamicIndexList". |
listId | String | Yes | Identifier to distinguish between different datasources in the same APL document. |
startIndex | Integer | Yes | Index of the leading item in the items array. Specify a non-zero value to start the experience at an arbitrary offset. For example, show an alphabetical list of contact names beginning 'M'. |
minimumInclusiveIndex | Integer | No | The index of the first item in the array, inclusive. The list is a backward-scrolling list if minimumInclusiveIndex is less than startIndex . When not specified, the list is backwards scrollable, but the first index of the array is unknown. Explicitly set this property equal to the startIndex property to make a list that doesn't load any more items when the user scrolls backwards. |
maximumExclusiveIndex | Integer | No | The last index of the array, exclusive. When not set, the list is a forward-scrolling list, but the final index of the array is unknown. Explicitly set this property to the last index of the items array + 1 to make a list that doesn't load any more items when the user scrolls forward. For example, to create a simple forward-scrolling experience across 200 items, set startIndex and minimumInclusiveIndex to 0, and maximumExclusiveIndex to 200. After all items from 0 to 199 have loaded, Alexa no longer asks your skill for more items. |
items | Array | No | Array of object data of the first items to render (with the leading element indexed at startIndex). Alexa displays the leading item at the top/left of the visible list area. |
This example shows a dynamicIndexList
data source that initially displays ten items. Alexa asks for more items to load when the user scrolls forward until all 200 items have loaded.
{
"dynamicSourceExample": {
"type": "dynamicIndexList",
"listId": "my-list-id",
"startIndex": 0,
"minimumInclusiveIndex": 0,
"maximumExclusiveIndex": 200,
"items": [
{"primaryText":"item 1"},
{"primaryText":"item 2"},
{"primaryText":"item 3"},
{"primaryText":"item 4"},
{"primaryText":"item 5"},
{"primaryText":"item 6"},
{"primaryText":"item 7"},
{"primaryText":"item 8"},
{"primaryText":"item 9"},
{"primaryText":"item 10"}
]
}
}
dynamicIndexList
into your document. Use a dynamicIndexList
solely to deliver the list items to display. Use a separate data source to bind other data to your document.Bind a dynamicIndexList data source
To use a dynamicIndexList
data source in your document, you must use the data source key in the mainTemplate.parameter
. Don't use the pre-1.3 "payload" parameter.
Then, use the data source key in the data-binding expression. For example, if your data source is called dynamicSourceExample
, use the expression ${dynamicSourceExample}
. This syntax provides your document with the set of items in the items
property. Don't include the items
property in the expression.
Bind the data source to the data
property of a Pager
, Sequence
, or Container
. Note that Container
does not support lazy loading, but it does support dynamic data sources. You can't use a dynamicIndexList
with any other component types.
This example shows a Sequence
that displays the ten items defined in the dynamicSourceExample
data source shown earlier.
{
"type": "APL",
"version": "1.3",
"mainTemplate": {
"parameters": [
"dynamicSourceExample"
],
"items": [
{
"type": "Sequence",
"data": "${dynamicSourceExample}",
"items": {
"type": "Text",
"text": "${data.primaryText}"
}
}
]
}
}
Use directives and requests to manage the list
To load items progressively, send the dynamicDataIndex
data source with your initial set of items in the RenderDocument
directive. As the user scrolls the list, Alexa sends your skill LoadIndexListData
requests to ask for more items to display. Your skill then returns the SendIndexListData
directive with another dynamicIndexList
data source containing the next set of items to display.
To change the contents of the list, send the initial dynamicIndexList
data source with a set of list items in the RenderDocument
directive. Then use the UpdateIndexListData
directive to make updates such as inserting new items or deleting existing items.
Sequence component size and the number of items to load
When you use a dynamicDataIndex
data source with a Sequence
for lazy loading, send enough items to fill the Sequence
at least three times in each response. For example, if the Sequence
is tall enough to display five items, your initial dynamicDataIndex
should contain at least 15 items. Each subsequent SendIndexListData
directive should also contain at least 15 items. The same applies for a horizontally-scrolling Sequence
. If the Sequence
is wide enough to display five items, send at least 15 in each call.
Providing a large enough set of items improves the list performance and user experience. If you send a small number of items in each response, the user experience might be poor as Alexa must then continually request new items as the user scrolls.
To ensure that the Sequence
height or width is static when loading items and scrolling, don't use the auto
setting for the height
or width
properties on the Sequence.
Set the Sequence
size to either a relative or absolute dimension.