InfluxDB HTTP API with Spring RestTemplate and Jackson TreeNode

In a recent project, I worked on interfacing with the InfluxDB HTTP API /query endpoint. InfluxDB is a time series database. The query endpoint accepts SELECT statements with GET. It returns query results in JSON, like this


{"results":[{
         "statement_id":0,
         "series":[{
               "name":"mymeas",
               "columns":[
                  "time",
                  "myfield",
                  "mytag1",
                  "mytag2"
               ],
               "values":[
                  [
                     "2017-03-01T00:16:18Z",
                     33.1,
                     null,
                     null
                  ],
                  [
                     "2017-03-01T00:17:18Z",
                     12.4,
                     "12",
                     "14"
                  ]
               ]
            }]
      }]
}

Previously, I have only worked with JSON using Java POJOs. I would create Java classes representing the JSON document structure, and then unmarshalled the JSON into Java objects. However, looking at the response body returned by the InfluxDB API, mapping the entire document structure seemed an overkill to me. I would need to create classes representing results, series, columns and values. When all I was interested in was the values JSON array.

I knew there must be an interface similar to the HTML DOM Parser, which I could use to traverse down a tree representation to reach the values array. I found the TreeNode interface in the Jackson documentation.

Below is the Java code to interface with InfluxDB HTTP query API with Spring RestTemplate and Jackson TreeNodes (without any error handling).


UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(url)
			        .queryParam("u", username)
			        .queryParam("p", password)
			        .queryParam("db", db)
			        .queryParam("q", select);

ObjectNode response = restTemplate.getForObject(builder.build().toUri(), ObjectNode.class);

Iterator<JsonNode> iter = response.get("results").get(0).get("series").get(0).get("values").elements();

while(iter.hasNext()) {
    JsonNode n = iter.next();
    // do something
}

Line 1 to 5 creates URL with the necessary query parameters. Line 7 calls the InfluxDB API endpoint using Spring RestTemplate, and converts the response body into a Jackson ObjectNode. Line 9 uses get() in ObjectNode repeatedly to access the values JSON array. It then use elements() to access all the value nodes with an iterator. Line 11 to 14 iterates the individual value array.

Note: I used spring-web version 5.1.5.RELEASE and jackson-databind version 2.9.8.