IoTDB 的 RESTful 服务可用于查询、写入和管理操作,它使用 OpenAPI 标准来定义接口并生成框架。
RESTful 服务默认情况是关闭的
找到IoTDB安装目录下面的conf/iotdb-system.properties文件,将 enable_rest_service 设置为 true 以启用该模块。
enable_rest_service=true
除了检活接口 /ping,RESTful 服务使用了基础(basic)鉴权,每次 URL 请求都需要在 header 中携带 'Authorization': 'Basic ' + base64.encode(username + ':' + password)。
示例中使用的用户名为:root,密码为:TimechoDB@2021,对应的 Basic 鉴权 Header 格式为
Authorization: Basic cm9vdDpyb290
若用户名密码认证失败,则返回如下信息:
HTTP 状态码:401
返回结构体如下
{ "code": 600, "message": "WRONG_LOGIN_PASSWORD_ERROR" }
若未设置 Authorization,则返回如下信息:
HTTP 状态码:401
返回结构体如下
{ "code": 603, "message": "UNINITIALIZED_AUTH_ERROR" }
ping 接口可以用于线上服务检活。
请求方式:GET
请求路径:http://ip:port/ping
请求示例:
$ curl http://127.0.0.1:18080/ping
返回的 HTTP 状态码:
200:当前服务工作正常,可以接收外部请求。503:当前服务出现异常,不能接收外部请求。响应参数:
| 参数名称 | 参数类型 | 参数描述 |
|---|---|---|
| code | integer | 状态码 |
| message | string | 信息提示 |
响应示例:
HTTP 状态码为 200 时:
{ "code": 200, "message": "SUCCESS_STATUS" }
HTTP 状态码为 503 时:
{ "code": 500, "message": "thrift service is unavailable" }
/ping接口访问不需要鉴权。
query 接口可以用于处理数据查询和元数据查询。
请求方式:POST
请求头:application/json
请求路径: http://ip:port/rest/v2/query
参数说明:
| 参数名称 | 参数类型 | 是否必填 | 参数描述 |
|---|---|---|---|
| sql | string | 是 | |
| row_limit | integer | 否 | 一次查询能返回的结果集的最大行数。 如果不设置该参数,将使用配置文件的 rest_query_default_row_size_limit 作为默认值。当返回结果集的行数超出限制时,将返回状态码 411。 |
响应参数:
| 参数名称 | 参数类型 | 参数描述 |
|---|---|---|
| expressions | array | 用于数据查询时结果集列名的数组,用于元数据查询时为null |
| column_names | array | 用于元数据查询结果集列名数组,用于数据查询时为null |
| timestamps | array | 时间戳列,用于元数据查询时为null |
| values | array | 二维数组,第一维与结果集列名数组的长度相同,第二维数组代表结果集的一列 |
请求示例如下所示:
提示:为了避免OOM问题,不推荐使用select * from root.xx.** 这种查找方式。
curl -H "Content-Type:application/json" -H "Authorization:Basic cm9vdDpyb290" -X POST --data '{"sql":"select s3, s4, s3 + 1 from root.sg27 limit 2"}' http://127.0.0.1:18080/rest/v2/query
{ "expressions": [ "root.sg27.s3", "root.sg27.s4", "root.sg27.s3 + 1" ], "column_names": null, "timestamps": [ 1635232143960, 1635232153960 ], "values": [ [ 11, null ], [ false, true ], [ 12.0, null ] ] }
2.请求示例 show child paths:
curl -H "Content-Type:application/json" -H "Authorization:Basic cm9vdDpyb290" -X POST --data '{"sql":"show child paths root"}' http://127.0.0.1:18080/rest/v2/query
{ "expressions": null, "column_names": [ "child paths" ], "timestamps": null, "values": [ [ "root.sg27", "root.sg28" ] ] }
curl -H "Content-Type:application/json" -H "Authorization:Basic cm9vdDpyb290" -X POST --data '{"sql":"show child nodes root"}' http://127.0.0.1:18080/rest/v2/query
{ "expressions": null, "column_names": [ "child nodes" ], "timestamps": null, "values": [ [ "sg27", "sg28" ] ] }
curl -H "Content-Type:application/json" -H "Authorization:Basic cm9vdDpyb290" -X POST --data '{"sql":"show all ttl"}' http://127.0.0.1:18080/rest/v2/query
{ "expressions": null, "column_names": [ "database", "ttl" ], "timestamps": null, "values": [ [ "root.sg27", "root.sg28" ], [ null, null ] ] }
curl -H "Content-Type:application/json" -H "Authorization:Basic cm9vdDpyb290" -X POST --data '{"sql":"show ttl on root.sg27"}' http://127.0.0.1:18080/rest/v2/query
{ "expressions": null, "column_names": [ "database", "ttl" ], "timestamps": null, "values": [ [ "root.sg27" ], [ null ] ] }
curl -H "Content-Type:application/json" -H "Authorization:Basic cm9vdDpyb290" -X POST --data '{"sql":"show functions"}' http://127.0.0.1:18080/rest/v2/query
{ "expressions": null, "column_names": [ "function name", "function type", "class name (UDF)" ], "timestamps": null, "values": [ [ "ABS", "ACOS", "ASIN", ... ], [ "built-in UDTF", "built-in UDTF", "built-in UDTF", ... ], [ "org.apache.iotdb.db.query.udf.builtin.UDTFAbs", "org.apache.iotdb.db.query.udf.builtin.UDTFAcos", "org.apache.iotdb.db.query.udf.builtin.UDTFAsin", ... ] ] }
curl -H "Content-Type:application/json" -H "Authorization:Basic cm9vdDpyb290" -X POST --data '{"sql":"show timeseries"}' http://127.0.0.1:18080/rest/v2/query
{ "expressions": null, "column_names": [ "timeseries", "alias", "database", "dataType", "encoding", "compression", "tags", "attributes" ], "timestamps": null, "values": [ [ "root.sg27.s3", "root.sg27.s4", "root.sg28.s3", "root.sg28.s4" ], [ null, null, null, null ], [ "root.sg27", "root.sg27", "root.sg28", "root.sg28" ], [ "INT32", "BOOLEAN", "INT32", "BOOLEAN" ], [ "RLE", "RLE", "RLE", "RLE" ], [ "SNAPPY", "SNAPPY", "SNAPPY", "SNAPPY" ], [ null, null, null, null ], [ null, null, null, null ] ] }
curl -H "Content-Type:application/json" -H "Authorization:Basic cm9vdDpyb290" -X POST --data '{"sql":"show latest timeseries"}' http://127.0.0.1:18080/rest/v2/query
{ "expressions": null, "column_names": [ "timeseries", "alias", "database", "dataType", "encoding", "compression", "tags", "attributes" ], "timestamps": null, "values": [ [ "root.sg28.s4", "root.sg27.s4", "root.sg28.s3", "root.sg27.s3" ], [ null, null, null, null ], [ "root.sg28", "root.sg27", "root.sg28", "root.sg27" ], [ "BOOLEAN", "BOOLEAN", "INT32", "INT32" ], [ "RLE", "RLE", "RLE", "RLE" ], [ "SNAPPY", "SNAPPY", "SNAPPY", "SNAPPY" ], [ null, null, null, null ], [ null, null, null, null ] ] }
curl -H "Content-Type:application/json" -H "Authorization:Basic cm9vdDpyb290" -X POST --data '{"sql":"count timeseries root.**"}' http://127.0.0.1:18080/rest/v2/query
{ "expressions": null, "column_names": [ "count" ], "timestamps": null, "values": [ [ 4 ] ] }
curl -H "Content-Type:application/json" -H "Authorization:Basic cm9vdDpyb290" -X POST --data '{"sql":"count nodes root.** level=2"}' http://127.0.0.1:18080/rest/v2/query
{ "expressions": null, "column_names": [ "count" ], "timestamps": null, "values": [ [ 4 ] ] }
curl -H "Content-Type:application/json" -H "Authorization:Basic cm9vdDpyb290" -X POST --data '{"sql":"show devices"}' http://127.0.0.1:18080/rest/v2/query
{ "expressions": null, "column_names": [ "devices", "isAligned" ], "timestamps": null, "values": [ [ "root.sg27", "root.sg28" ], [ "false", "false" ] ] }
curl -H "Content-Type:application/json" -H "Authorization:Basic cm9vdDpyb290" -X POST --data '{"sql":"show devices with database"}' http://127.0.0.1:18080/rest/v2/query
{ "expressions": null, "column_names": [ "devices", "database", "isAligned" ], "timestamps": null, "values": [ [ "root.sg27", "root.sg28" ], [ "root.sg27", "root.sg28" ], [ "false", "false" ] ] }
curl -H "Content-Type:application/json" -H "Authorization:Basic cm9vdDpyb290" -X POST --data '{"sql":"list user"}' http://127.0.0.1:18080/rest/v2/query
{ "expressions": null, "column_names": [ "user" ], "timestamps": null, "values": [ [ "root" ] ] }
curl -H "Content-Type:application/json" -H "Authorization:Basic cm9vdDpyb290" -X POST --data '{"sql":"select count(*) from root.sg27"}' http://127.0.0.1:18080/rest/v2/query
{ "expressions": [ "count(root.sg27.s3)", "count(root.sg27.s4)" ], "column_names": null, "timestamps": [ 0 ], "values": [ [ 1 ], [ 2 ] ] }
curl -H "Content-Type:application/json" -H "Authorization:Basic cm9vdDpyb290" -X POST --data '{"sql":"select count(*) from root.** group by level = 1"}' http://127.0.0.1:18080/rest/v2/query
{ "expressions": null, "column_names": [ "count(root.sg27.*)", "count(root.sg28.*)" ], "timestamps": null, "values": [ [ 3 ], [ 3 ] ] }
curl -H "Content-Type:application/json" -H "Authorization:Basic cm9vdDpyb290" -X POST --data '{"sql":"select count(*) from root.sg27 group by([1635232143960,1635232153960),1s)"}' http://127.0.0.1:18080/rest/v2/query
{ "expressions": [ "count(root.sg27.s3)", "count(root.sg27.s4)" ], "column_names": null, "timestamps": [ 1635232143960, 1635232144960, 1635232145960, 1635232146960, 1635232147960, 1635232148960, 1635232149960, 1635232150960, 1635232151960, 1635232152960 ], "values": [ [ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] ] }
curl -H "Content-Type:application/json" -H "Authorization:Basic cm9vdDpyb290" -X POST --data '{"sql":"select last s3 from root.sg27"}' http://127.0.0.1:18080/rest/v2/query
{ "expressions": null, "column_names": [ "timeseries", "value", "dataType" ], "timestamps": [ 1635232143960 ], "values": [ [ "root.sg27.s3" ], [ "11" ], [ "INT32" ] ] }
curl -H "Content-Type:application/json" -H "Authorization:Basic cm9vdDpyb290" -X POST --data '{"sql":"select * from root.sg27 disable align"}' http://127.0.0.1:18080/rest/v2/query
{ "code": 407, "message": "disable align clauses are not supported." }
curl -H "Content-Type:application/json" -H "Authorization:Basic cm9vdDpyb290" -X POST --data '{"sql":"select count(s3) from root.sg27 align by device"}' http://127.0.0.1:18080/rest/v2/query
{ "code": 407, "message": "align by device clauses are not supported." }
curl -H "Content-Type:application/json" -H "Authorization:Basic cm9vdDpyb290" -X POST --data '{"sql":"select s3, s4 into root.sg29.s1, root.sg29.s2 from root.sg27"}' http://127.0.0.1:18080/rest/v2/query
{ "code": 407, "message": "select into clauses are not supported." }
请求方式:POST
请求头:application/json
请求路径:http://ip:port/rest/v2/nonQuery
参数说明:
| 参数名称 | 参数类型 | 是否必填 | 参数描述 |
|---|---|---|---|
| sql | string | 是 |
请求示例:
curl -H "Content-Type:application/json" -H "Authorization:Basic cm9vdDpyb290" -X POST --data '{"sql":"CREATE DATABASE root.ln"}' http://127.0.0.1:18080/rest/v2/nonQuery
响应参数:
| 参数名称 | 参数类型 | 参数描述 |
|---|---|---|
| code | integer | 状态码 |
| message | string | 信息提示 |
响应示例:
{ "code": 200, "message": "SUCCESS_STATUS" }
请求方式:POST
请求头:application/json
请求路径:http://ip:port/rest/v2/insertTablet
参数说明:
| 参数名称 | 参数类型 | 是否必填 | 参数描述 |
|---|---|---|---|
| timestamps | array | 是 | 时间列 |
| measurements | array | 是 | 测点名称 |
| data_types | array | 是 | 数据类型 |
| values | array | 是 | 值列,每一列中的值可以为 null |
| is_aligned | boolean | 是 | 是否是对齐时间序列 |
| device | string | 是 | 设备名称 |
请求示例:
curl -H "Content-Type:application/json" -H "Authorization:Basic cm9vdDpyb290" -X POST --data '{"timestamps":[1635232143960,1635232153960],"measurements":["s3","s4"],"data_types":["INT32","BOOLEAN"],"values":[[11,null],[false,true]],"is_aligned":false,"device":"root.sg27"}' http://127.0.0.1:18080/rest/v2/insertTablet
响应参数:
| 参数名称 | 参数类型 | 参数描述 |
|---|---|---|
| code | integer | 状态码 |
| message | string | 信息提示 |
响应示例:
{ "code": 200, "message": "SUCCESS_STATUS" }
请求方式:POST
请求头:application/json
请求路径:http://ip:port/rest/v2/insertRecords
参数说明:
| 参数名称 | 参数类型 | 是否必填 | 参数描述 |
|---|---|---|---|
| timestamps | array | 是 | 时间列 |
| measurements_list | array | 是 | 测点名称 |
| data_types_list | array | 是 | 数据类型 |
| values_list | array | 是 | 值列,每一列中的值可以为 null |
| devices | string | 是 | 设备名称 |
| is_aligned | string | 是 | 是否是对齐时间序列 |
请求示例:
curl -H "Content-Type:application/json" -H "Authorization:Basic cm9vdDpyb290" -X POST --data '{"timestamps":[1635232113960,1635232151960,1635232143960,1635232143960],"measurements_list":[["s33","s44"],["s55","s66"],["s77","s88"],["s771","s881"]],"data_types_list":[["INT32","INT64"],["FLOAT","DOUBLE"],["FLOAT","DOUBLE"],["BOOLEAN","TEXT"]],"values_list":[[1,11],[2.1,2],[4,6],[false,"cccccc"]],"is_aligned":false,"devices":["root.s1","root.s1","root.s1","root.s3"]}' http://127.0.0.1:18080/rest/v2/insertRecords
响应参数:
| 参数名称 | 参数类型 | 参数描述 |
|---|---|---|
| code | integer | 状态码 |
| message | string | 信息提示 |
响应示例:
{ "code": 200, "message": "SUCCESS_STATUS" }
配置位于 iotdb-system.properties 中。
enable_rest_service 设置为 true 以启用该模块,而将 false 设置为禁用该模块。默认情况下,该值为 false。enable_rest_service=true
enable_rest_service=true 时生效。将 rest_service_port 设置为数字(1025~65535),以自定义REST服务套接字端口。默认情况下,值为 18080。rest_service_port=18080
false。enable_swagger=false
411。rest_query_default_row_size_limit=10000
cache_expire=28800
cache_max_num=100
cache_init_num=10
enable_https 设置为 true 以启用该模块,而将 false 设置为禁用该模块。默认情况下,该值为 false。enable_https=false
key_store_path=
key_store_pwd=
trust_store_path=
trust_store_pwd=
idle_timeout=5000