TREVL can fetch data from any REST API through the DataSource::Api data source. You configure a base URL and authentication, then reference API response fields in your YAML using the $ reference syntax.
Connecting an API
Register a data source with a name, base URL, and optional authentication:
Trevl::DataSource.register("myapi", Trevl::DataSource::Api.new(
base_url: "https://api.example.com/v1",
auth: Trevl::Auth::BearerToken.new(ENV["API_TOKEN"])
))
Then use that name in your TREVL components:
id: salary-chart
type: chart
api: myapi
api-parameters:
profession:
id: "43104"
taxonomy: kldb
location:
country: DE
time:
start_month_offset: -12
end_month_offset: 0
highchartsData:
series:
- data:
y: "$salary.data.q50"
Reference Syntax
API data sources use a structured $-reference syntax with three levels: endpoint, scope, and field.
Standard form
$endpoint.data.field # row data
$endpoint.meta.field # response metadata
Examples:
y: "$salary.data.q50" # salary quantile from row
name: "$skills.data.label" # skill name from row
total: "$vacancies.meta.total_results" # total from metadata
Resource-qualified form
When your API has multiple resource namespaces, prefix with the resource name:
$resource.endpoint.data.field
$resource.endpoint.meta.field
Examples:
y: "$professions.salary.data.q50" # explicit resource
y: "$surveys.distribution.data.share" # different resource
Legacy short form
For backward compatibility, the two-segment form still works:
y: "$salary.q50" # equivalent to $salary.data.q50
api-parameters
The api-parameters section defines what gets sent in the request body. Only parameters you explicitly define are sent.
api-parameters:
profession:
id: "43104"
taxonomy: kldb
location:
country: DE
time:
start_month_offset: -12
end_month_offset: 0
language: de
limit: 25
Runtime parameter overrides
When a component is rendered in a specific context, parameters can be overridden at render time:
Trevl.render(yaml, params: {
"param_override" => {"profession" => {"id" => "52101", "taxonomy" => "kldb"}}
})
This merges into the api-parameters, so the same component works for different contexts.
Discovering Fields
Before writing TREVL, you can discover what fields an API endpoint returns:
source = Trevl::DataSource.for("myapi")
source.field_names("salary")
# => ["date", "q10", "q25", "q50", "q75", "q90"]
This fetches a sample row and returns its keys. Use this to avoid guessing field names in your $ references.
Response Format
The API data source expects JSON responses in one of these formats:
Array of objects
[
{"label": "Python", "value": 85},
{"label": "Ruby", "value": 45}
]
Object with results/data key
{
"results": [
{"label": "Python", "value": 85}
],
"metadata": {"total": 42}
}
Both results and data are recognized as the data array. Both metadata and meta are recognized as metadata.
Example: Chart from a REST API
id: skills-chart
type: chart
api: myapi
api-parameters:
language: en
limit: 10
highchartsData:
chart:
type: bar
title:
text: Top Skills
series:
- name: Relevance
data:
x: "$skills.data.label"
y: "$skills.data.value"
Example: Table from a REST API
id: vacancy-table
type: table
api: myapi
api-parameters:
location:
country: DE
limit: 20
tableData:
headers: ["Title", "Company", "Location"]
columns:
- identifier: title
value: "$vacancies.data.title"
- identifier: company
value: "$vacancies.data.company"
- identifier: location
value: "$vacancies.data.city"
Postprocess with API data
API components can use postprocess to transform the fetched data. The $result variable contains the rows:
postprocess: |
$result = $result
.sort(function(a, b) { return b.value - a.value; })
.slice(0, 5);
Always guard against empty data – the API may return no results for certain parameters.
Computed fields with API data
Computed fields work the same way as with any data source. Arguments can reference $endpoint.data.* and $endpoint.meta.*:
computed:
- name: share_percent
arguments:
raw: "$skills.data.value"
code: "Math.round(raw * 100) / 100"
Custom Authentication
The Auth::BearerToken class covers most APIs. For other auth methods, pass any object that responds to #apply(headers, url:):
class MyApiKeyAuth
def initialize(key)
@key = key
end
def apply(headers, url: nil)
headers["X-API-Key"] = @key
end
end
Trevl::DataSource.register("myapi", Trevl::DataSource::Api.new(
base_url: "https://api.example.com",
auth: MyApiKeyAuth.new(ENV["API_KEY"])
))