Hardware

Filter API responses with Output Filters on ARTIK


In this tutorial, we'll show how you Temboo makes it simple to retrieve only the information you care about from an API response.

Many APIs return complex JSON or XML data that can be difficult to parse, particularly on microcontroller devices with limited memory. But with Temboo, you can select which pieces of JSON or XML data you’d like to have returned. The key is specifying one or more Output Filters when you call a Choreo. We'll demonstrate this with the Yahoo! Weather Choreo used in our Getting Started tutorial.

Filtering API Responses

When you run the code from our getting started example, you'll see an XML response returned by Yahoo! Weather printed to the console. Let's use Output Filters to extract just the date of the last weather report and the current temperature from this XML.

1Add the following lines of code to the Yahoo! WeatherByAddress your code, just before the line that calls the run() method:

// add an output filter to extract the current temperature
ChoreoOutput tempOut;
tempOut.name = "temperature";
tempOut.xpath = "/rss/channel/item/yweather:condition/@temp";
tempOut.variable = "Response";
addChoreoOutput(&choreo, &tempOut);

// add an output filter to extract the date and time of the last report.
ChoreoOutput dateOut;
dateOut.name = "date";
dateOut.xpath = "/rss/channel/item/yweather:condition/@date";
dateOut.variable = "Response";
addChoreoOutput(&choreo, &dateOut);

2Now build and run the code. Instead of seeing the XML returned by Yahoo! Weather, you should now see individual values for "temperature" and "date" in a format that can be read into individual variables for use in your code.

What Just Happened?

Output Filters provide a powerful mechanism for reducing the complexity of API responses. To understand how they work, we'll walk through the process of creating a new Output Filter from scratch.

As we saw above, each Output Filter is constructed with three parameters, in the format: Choreo.addOutputFilter(result_label, data_path, choreo_output).

Result label is how you’d like Temboo to label this piece of information when it’s returned to your code. Labels can contain letters and numbers, and you can choose any label you’d like for an Output Filter.

Data path is used to identify the particular item within a JSON or XML response that you’d like to have returned. The data path can either be an XPath statement, or a JSON path.

Choreo output is the name of the Choreo output that contains the JSON or XML data to be filtered.

Identifying the Data to Filter

To construct an Output Filter, you’ll need to create an XPath or JSON path statement that identifies the data within the API response you want returned.

For example, given the response XML:

<weather>
    <current>
        <temperature>68</temperature>
        <humidity>45</humidity>
    </current>
</weather>

To return only the value of the <temperature> element, your XPath statement would be:

/weather/current/temperature

If you’re not familiar with XPath, you can find a good general introduction here. There are also a number of useful online tools that can help with constructing XPath statements, like the this one.

The paths you use to specify JSON elements work much the same way (although they don’t support more advanced XPath features like attribute-value selectors). Given the JSON:

{
    “weather” : {
        “temperature”: “68”,
        “humidity”: “45”
    }
}

To retrieve the “temperature” value, you’d specify a data path of:

/weather/temperature

In cases where you need to get a JSON or XML element at a particular array index, you can use the square bracket syntax to specify which element in the array you want. Array indices start at 1 (rather than 0). So to retrieve the first element in the /weather/temperature array, you'd use:

/weather/temperature[1]

If you want to return all elements in a collection, you specify empty brackets, [], after the collection in question. So, to retrieve all elements in the /weather/temperature array, you'd use:

/weather/temperature[]

If you're targeting a collection that is at the top-level of the returned data, you can start your Output Filter specification with empty brackets e.g., /[]/var_name1/var_name2.

In this example, we'll define an additional output filter for the Yahoo! Weather API to extract the forecast city from the response XML.

Assembling the Output Filter

When constructing an Output Filter, you’ll typically need to start with a sample of the JSON or XML returned by the Choreo. Running a Choreo from the Temboo website is a convenient way to obtain this output.

To create the Output Filter, follow these steps:

1Run the Yahoo > Weather > WeatherByAddress Choreo using the Temboo website (using the same process explained in the first Getting Started tutorial). After the Choreo runs, you’ll see the XML returned in the Output section.

2Note the name of the Choreo output for which the XML data was returned. Some Choreos have more than one named output. In most cases, for Library Choreos, the relevant Choreo output name will be Response, like in the screenshot below.

Yahoo! Weather Response Output

A Choreo output named Response

3Identify the XPath or JSON path for the filtered information you want returned by Temboo.

The XML returned by the Yahoo > Weather > GetWeatherByAddress looks like:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<rss xmlns:yweather="http://xml.weather.yahoo.com/ns/rss/1.0" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" version="2.0">
<channel>
    <title>Yahoo! Weather - Portland, OR</title>
    <link>http://us.rd.yahoo.com/dailynews/rss/weather/Portland__OR/*http://weather.yahoo.com/forecast/USWA0468_f.html</link>
    <description>Yahoo! Weather for Portland, OR</description>
    <language>en-us</language>
    <lastBuildDate>Mon, 24 Jun 2013 11:53 am PDT</lastBuildDate>
    <ttl>60</ttl>
    <yweather:location city="Portland" region="OR" country="United States"/>
    <yweather:units temperature="F" distance="mi" pressure="in" speed="mph"/>
    <yweather:wind chill="60" direction="170" speed="5"/>
    <yweather:atmosphere humidity="80" visibility="10" pressure="29.72" rising="0"/>
    <yweather:astronomy sunrise="5:21 am" sunset="9:01 pm"/>
    <image>
        <title>Yahoo! Weather</title>
        <width>142</width>
        <height>18</height>
        <link>http://weather.yahoo.com</link>
        <url>http://l.yimg.com/a/i/brand/purplelogo//uh/us/news-wea.gif</url>
    </image>
    <item>
        <title>Conditions for Portland, OR at 11:53 am PDT</title>
        <geo:lat>45.58</geo:lat>
        <geo:long>-122.69</geo:long>
        <link>http://us.rd.yahoo.com/dailynews/rss/weather/Portland__OR/*http://weather.yahoo.com/forecast/USWA0468_f.html</link>
        <pubDate>Mon, 24 Jun 2013 11:53 am PDT</pubDate>
        <yweather:condition text="Light Rain" code="11" temp="60" date="Mon, 24 Jun 2013 11:53 am PDT"/>

Note: the full XML response has been shortened here for clarity.

We’ll want to retrieve the value of the city attribute within the <yweather:location> element. The XPath statement for this value will be:

/rss/channel/yweather:location/@city

That is, the city attribute (specified by the "@" symbol) within the XML element located at /rss/channel/yweather:location. Note that you could also specify this element using:

//yweather:location/@city

(The // means "regardless of the parent XML element’s location.")

4Finally, choose a label that Temboo will use to identify the filtered data when it’s returned to the LaunchPad. In this case, we’ll use city as the label.

We now have all the pieces to assemble the output filter:

Using Output Filters

After defining the components of your Output Filter, you can fill in the variables in the ChoreoOutput structure. You can then specify it as a parameter argument in your code using the addChoreoOutput(TembooChoreo* chroeo, ChoreoOutput* output) function before the run() method. For this Output Filter, the code will look like:

// add an output filter to extract the current temperature
ChoreoOutput cityOut;
cityOut.name = "city";
cityOut.xpath = "/rss/channel/yweather:location/@city";
cityOut.variable = "Response";
addChoreoOutput(&choreo, &cityOut);

ChoreoOutput tempOut;
tempOut.name = "temperature";
tempOut.xpath = "/rss/channel/item/yweather:condition/@temp";
tempOut.variable = "Response";
addChoreoOutput(&choreo, &tempOut);

// add an output filter to extract the date and time of the last report.
ChoreoOutput dateOut;
dateOut.name = "date";
dateOut.xpath = "/rss/channel/item/yweather:condition/@date";
dateOut.variable = "Response";
addChoreoOutput(&choreo, &dateOut);

5That's it! Now when you run the Choreo, you'll see the data that you've filtered for rather than a whole load of data that you don't need.

Save and run your code. You should now see individual outputs for "city," "temperature," and "date" printed to the console.

Need Help?

We're always happy to help. Just email us at support@temboo.com, and we'll answer your questions.


Back