HTTP Client API
This document will cover the API calls for accessing Riak TS data over HTTP.
Overview
All Riak TS calls use the ‘/ts’ endpoint. Using the following table schema, each API call has a corresponding URL:
CREATE TABLE GeoCheckin
(
region VARCHAR NOT NULL,
state VARCHAR NOT NULL,
time TIMESTAMP NOT NULL,
weather VARCHAR NOT NULL,
temperature DOUBLE,
PRIMARY KEY (
(region, state, QUANTUM(time, 15, 'm')),
region, state, time
)
)
Call | Request URL | Type | Description |
---|---|---|---|
put | /ts/v1/tables/GeoCheckin/keys ‘[»Row(s)«]’ | POST | put a single or a batch of rows |
get | /ts/v1/tables/GeoCheckin/keys/region/North%20West/state/WA/time/14201136 | GET | single-key get of a value |
delete | /ts/v1/tables/GeoCheckin/keys/region/North%20West/state/WA/time/14201136 | DELETE | single-key delete |
query | /ts/v1/query –data “»Query«” | POST | execute a query |
list_keys | /ts/v1/tables/GeoCheckin/list_keys | GET | streaming list keys |
The query
Call type supports SQL queries, so REST purists may think that the
HTTP verb should be GET
when the SQL command is a SELECT
targeting a single
record, DELETE
when the SQL command is a DELETE
targeting a single record,
POST
when the SQL command is an INSERT
, PUT
when the SQL command is an
UPDATE
targeting a single record. However, such purity attempts are stretched
to the breaking point for a SQL command of SELECT
, UPDATE
, or DELETE
targeting multiple records. As SQL is generally oriented at set-based operations
and REST is oriented towards single-document operations, using POST
to process
set-based operation should be apparently pure. This distinction should help the
developer in reasoning about Riak TS usage over HTTP, including how to properly
cache results, a primary reason for REST purity.
Percent-encoding
All keys need to be implemented in the query string using percent-encoding (or URL encoding), which can be seen in the examples above for the get
and delete
operations. Failing to do so will result in a 400 - Bad Request
response. Percent-encoding variants where a space character is replaced with a +
will work as expected, but it is recommended that modern variants are used where spaces are encoded as %20
.
Blob data
Riak TS 1.5 introduces raw binary data via the blob
data type. Although such data will be stored in binary inside Riak TS, JSON does not support raw binary data, so the data must be encoded before being sent to, or retrieved from, the server.
The encoding mechanism for binary data in the HTTP API depends on the interface being used.
Note: we do not currently recommend using blob
columns in the primary key because not all Riak TS APIs deal gracefully with them.
JSON and base64
Most binary data will be written to from Riak TS using base64 encoding inside JSON. This includes data uploaded via put
and keys specified as parameters to put
, get
, and delete
.
Blob data inside JSON retrieved from Riak TS will also be base64-encoded, including URLs returned from list_keys
.
Hex encoding
Any SQL queries executed via query
that include comparisons against a blob
column (currently, the only comparisons supported are equal to or not equal to) must encode the compared data in hex notation.
This notation is an integer value in base 16 preceded by 0x
. The ASCII string “hello” would look like 0x68656c6c6f
(or 0x68656C6C6F
). The value is an integer and thus is not escaped using apostrophes as a string value would be.
An example SQL query against a table with a blob
column named acceleration_stats
:
SELECT * FROM devices WHERE name = 'ACME anvil' and acceleration_stats = 0x001a5942 and time > 0 and time < 1000
The results from the query are in JSON and thus will be encoded as base64
, not hex.
Keys and Values
Call | Method | Type |
---|---|---|
put | POST | Write |
get | GET | Read |
delete | DELETE | Write |
query | POST | Query |
list_keys | GET | Read |
Single-key get
and delete
requires the complete primary key to be serialized in the path of the URL, using the order defined in the schema to determine which row to get. The entire row will be returned.
The put
call uses a full row or a list of full rows in order to add entries to the table. Each row is specified in a separate tuple.
Streaming list_keys
returns all the URLs as plain text separated by a new line for all the keys in the table.
The query
to be executed should be sent as a plain text string in the body of the request.
The value of »Server«
is the IP address of your system and the HTTP interface port, separated by a colon. This value is the listener.http.internal
setting in the riak.conf
file.
Returning Results
All request results will be JSON-encoded, except for the streaming list of keys which returns plain text.
Error conditions will be returned by a JSON structure containing an internal error code and a human-readable message, in addition to reporting HTTP status code in the response in the 400 range.
Examples
Let’s write the following rows to the table:
"Florida", "Miami", 1234567, "hot", 23.5
"Illinois", "Chicago", 1234568, "windy", 19.8
A put
call can be used to write the two rows:
$ curl -XPOST http://127.0.0.1:8098/ts/v1/tables/GeoCheckin/keys --data '[{"state":"Florida","city":"Miami","time":1234567,"weather":"hot","temperature":23.5},{"state":"Illinois","city":"Chicago","time":1234568,"weather":"windy","temperature":19.8}]'
{"success":true}
A get
call can be used to read one of the rows:
$ curl -XGET http://127.0.0.1:8098/ts/v1/tables/GeoCheckin/keys/state/Florida/city/Miami/time/1234567
{"state":"Florida","city":"Miami","time":1234567,"weather":"hot","temperature":23.5}
A query
call can be used to run a SELECT
query to display all columns of the GeoCheckin table and return all rows that satisfy the WHERE clause:
$ curl -XPOST http://127.0.0.1:8098/ts/v1/query --data "SELECT * FROM GeoCheckin WHERE state = 'Illinois' AND city = 'Chicago' AND time >= 1200000 and time <= 1500000"
{"columns":["state","city","time","weather","temperature"],"rows":[["Illinois","Chicago",1234568,"windy",19.8]]}
A list_keys
call can be used to stream a list of keys in the table:
$ curl -XGET http://127.0.0.1:8098/ts/v1/tables/GeoCheckin/list_keys
http://127.0.0.1:8098/ts/v1/tables/GeoCheckin/keys/state/Florida/city/Miami/time/1234567
http://127.0.0.1:8098/ts/v1/tables/GeoCheckin/keys/state/Illinois/city/Chicago/time/1234568
A delete
call can be used to delete one of the rows:
$ curl -XDELETE http://127.0.0.1:8098/ts/v1/tables/GeoCheckin/keys/state/Illinois/city/Chicago/time/1234568
{"success":true}
The following are bad calls that result in various errors:
$ curl -XPOST http://127.0.0.1:8098/ts/v1/query --data "CREATE TABLE GeoCheckin (state varchar not null, city varchar not null, time timestamp not null, weather varchar not null, temperature double, PRIMARY KEY ((state, city, quantum(timecol, 15, 'm')), state, city, time))"
Query error: Local key does not match primary key
$ curl -XPOST http://127.0.0.1:8098/ts/v1/tables/GeoCheckin/keys --data '[{"state":"Florida","city":"Miami","time":1234567,"weather":50,"temperature":23.5}]'
Bad value for field "weather" of type varchar in table "GeoCheckin"
$ curl -XGET http://127.0.0.1:8098/ts/v1/tables/GeoCheckin2/keys/state/Florida/city/Miami/time/1234567
Table "GeoCheckin2" does not exist
$ curl -XPOST http://192.168.99.14:8098/ts/v1/query --data "SELECT ? FROM GeoCheckin WHERE state = 'Illinois' AND city = 'Chicago' AND time >= 1200000 and time <= 1500000"
Query error: Unexpected token '?'.
$ curl -XDELETE http://127.0.0.1:8098/ts/v1/tables/GeoCheckin/keys/state/Colorado/city/Denver/time/1234570
Key not found