Skip to content

Provide Data in any Format via a Custom API¤

Introduction¤

Learn how to provide data via a customized Corporate Memory API in a text format of your choice and how to consume it in your applications. This tutorial describes how you can provide data in a text format of your choice via your own custom Corporate Memory API, and how you request those APIs.

In this tutorial, we describe how you can set up an endpoint which provides iCalendar data. If you want to rebuild the example, you can download this iCalendar RDF data and import it into your Corporate Memory instance: ical_data.ttl

BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//hacksw/handcal//NONSGML v1.0//EN
BEGIN:VEVENT
UID:20020630T230353Z-3895-69-1-0@jammer
DTSTAMP:20020630T230353Z
DTSTART:20020630T090000Z
DTEND:20020630T103000Z
SUMMARY:Church
END:VEVENT
END:VCALENDAR

Define a SPARQL query¤

This query selects the event data in our graph which will be provided via the customized API. To rebuild the iCalendar format, we need at least the unique identifier (uid), the datetime start (dtstart), the datetime end (dtend), and the summary of the event. The query filters (REPLACE) the special characters : and - at the end as they are not needed in the iCal DateTime format.

PREFIX ical: <http://www.w3.org/2002/12/cal/icaltzd#>

SELECT DISTINCT ?vevent ?uid ?dtstamp ?dtstart ?dtend ?summary

WHERE {
?vevent a ical:Vevent .
    ?vevent ical:uid ?uid .
    ?vevent ical:dtstamp ?dtstamp_raw .
    ?vevent ical:dtstart ?dtstart_raw .
    ?vevent ical:dtend ?dtend_raw .
    ?vevent ical:summary ?summary  .

    BIND(REPLACE(STR(?dtstamp_raw),"[: -]","") AS ?dtstamp) .
    BIND(REPLACE(STR(?dtstart_raw),"[: -]","") AS ?dtstart) .
    BIND(REPLACE(STR(?dtend_raw),"[: -]","") AS ?dtend) .
}

Define a Template for the iCal format¤

As a next step, we will define a template that generates iCalendar data from our previously defined SPARQL query.

Select in Graphs the CMEM Query Catalog graph, select in Navigation the Select Result Template and click Create a new Select Result Template to create a new template.

result-template

create-result-template

Define a Name, a Description and the Body format. You may also define a header and/or a footer, however, this is not necessary for this example.

The template engine we are using Jinja. In Jinja, dynamic data within a template needs to be referenced via double curly brackets {{...}}. So the line {{result.uid}} inserts at execution time the ?uid value from our previously defined SPARQL query into this template. Everything outside curly brackets it static. As static data in our example, we define the full iCalendar format (..BEGIN:EVENT..). As we receive multiple results (iCalendar Events) from the SPARQL query, we have to iterate through each of them. To define this iteration in the template, the following line needs to be added:

{% for result in results %}

and for the conclusion of the iteration, this line needs to be added at the end:

{% endfor %}

sparql-result-template

Jira Template for our iCalendar format
BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//hacksw/handcal//NONSGML v1.0//EN
{% for result in results %}
BEGIN:VEVENT
UID:{{result.uid}}
DTSTAMP:{{result.dtstamp}}
DTSTART:{{result.dtstart}}
DTEND:{{result.dtend}}
SUMMARY:{{result.summary}}
END:VEVENT
{% endfor %}

END:VCALENDAR

Create an API based on your template¤

As a next step, we will set up the API which serves the data in the format we defined in the previous template.

Select in Graphs the CMEM Query Catalog graph, select in Navigation the Select Query Endpoint and click “Create a new Select Query Endpoint” to create a new endpoint.

query-endpoint

Define a Name, a human-readable keyword (i.e. the URL Slug) for the API path, specify if it is a Streaming endpoint (false in our example), enter a Description, and select the defined SPARQL Query from our first step and the Template we created in the second step. Once you press save, your endpoint it set up!

create-query-endpoint

Consume data via the endpoint¤

Now that the endpoint is defined, it is possible to make a request to receive the iCal data. The endpoint URL consist of the path /dataplatform/api/custom and the previously defined URL Slug (/ical). cmemc can be used to get the API base URL as well as a valid token:

curl request
$ curl "https://$(cmemc -c my config get DP_API_ENDPOINT)/api/custom/ical" \
    -H "Authorization: Bearer $(cmemc -c my admin token)"
API Response
BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//hacksw/handcal//NONSGML v1.0//EN

BEGIN:VEVENT
UID:20020630T230353Z-3895-69-1-0@jammer
DTSTAMP:20020630T230353Z
DTSTART:20020630T090000Z
DTEND:20020630T103000Z
SUMMARY:Church
END:VEVENT

BEGIN:VEVENT
UID:20020630T230445Z-3895-69-1-7@jammer
DTSTAMP:20020630T230445Z
DTSTART:20020703
DTEND:20020706
SUMMARY:Scooby Conference
END:VEVENT

BEGIN:VEVENT
UID:20020630T230600Z-3895-69-1-16@jammer
DTSTAMP:20020630T230600Z
DTSTART:20020718T090000
DTEND:20020718T093000
SUMMARY:Federal Reserve Board Meeting
END:VEVENT

END:VCALENDAR

This result is represented in valid ICalendar (ics) format and can be imported into your calendar client (event_data.ics).

Configuration remarks¤

Streaming¤

If Is Streaming is set to false for the endpoint (as in the given example), the respective Jinja Template needs to resolve a results variable, which is a list of all query results that needs to be iterated over using Jinja constructs:

{% for result in results %}

A non-streaming result set (the SPARQL query) is limited to 1000 elements. If more results are expected Is Streaming should be set to true.

If Is Streaming is set to true the Jinja Template has to resolve a result variable (without the ‘s’), which is a single query result. The template engine iterates over the results, i.e. the Body template is repeated for each query result.

Comments