JavaScript 客户端库入门程序
按照此分步教程,使用 InfluxData 客户端库和您最喜欢的框架或语言构建物联网 (IoT) 应用程序。
在本教程中,您将使用 InfluxDB API 和客户端库来构建现代应用程序,并学习以下内容
- InfluxDB 核心概念。
- 应用程序如何与设备和 InfluxDB 交互。
- 如何对应用程序和设备进行 API 身份验证。
- 如何安装客户端库。
- 如何在 InfluxDB 中写入和查询数据。
目录
- 目录
- 设置 InfluxDB
- IoT Starter 介绍
- 安装 Yarn
- 创建应用程序
- 安装 InfluxDB 客户端库
- 配置客户端库
- 构建 API
- 创建 API 以列出设备
- 创建 API 以注册设备
- 安装并运行 UI
设置 InfluxDB
如果您尚未这样做,请创建 InfluxDB Cloud 帐户或安装 InfluxDB OSS。
IoT Starter 示例应用程序假定以下先决条件
- InfluxDB 组织 ID
- 一个 API 令牌(例如,一个完全访问令牌),该令牌对存储桶具有读写权限
- 一个名为
iot_center
的存储桶,用于存储来自设备的时间序列数据 - 一个名为
iot_center_devices
的存储桶,用于存储设备元数据和 API 令牌 ID
对生产应用程序使用受限令牌
对于生产应用程序,创建并使用具有最小权限的 读写 令牌,并且仅将其与单个客户端或应用程序一起使用。
IoT Starter 介绍
应用程序架构有四个层
- InfluxDB API:InfluxDB v2 API。
- IoT 设备:虚拟或物理设备将 IoT 数据写入 InfluxDB API。
- UI:向服务器发送请求并在浏览器中渲染视图。
- API:接收来自 UI 的请求,向 InfluxDB 发送请求,并处理来自 InfluxDB 的响应。
有关本教程中引用的完整代码,请参阅 influxdata/iot-api-js 存储库。
安装 Yarn
如果您尚未安装 yarn
,请按照适用于您的 Node.js 版本的 Yarn 包管理器安装说明进行操作。
要检查已安装的
yarn
版本,请在您的终端中输入以下代码yarn --version
创建应用程序
创建一个将包含您的 iot-api
项目的目录。以下示例代码在您的主目录中创建一个 iot-api
目录,并切换到新目录
mkdir ~/iot-api-apps
cd ~/iot-api-apps
按照以下步骤使用 Next.js 创建 JavaScript 应用程序
在您的
~/iot-api-apps
目录中,打开一个终端并输入以下命令,从 NextJS learn-starter 模板创建iot-api-js
应用程序yarn create-next-app iot-api-js --example "https://github.com/vercel/next-learn/tree/master/basics/learn-starter"
安装完成后,在您的终端中输入以下命令以进入您的
./iot-api-js
目录并启动开发服务器cd iot-api-js yarn dev -p 3001
要查看应用程序,请在您的浏览器中访问 https://127.0.0.1:3001。
安装 InfluxDB 客户端库
InfluxDB 客户端库提供以下 InfluxDB API 交互
- 使用 Flux 语言查询数据。
- 将数据写入 InfluxDB。
- 在后台批量处理数据。
- 在失败时自动重试请求。
在您的终端中输入以下命令以安装客户端库
yarn add @influxdata/influxdb-client
在您的终端中输入以下命令以安装
@influxdata/influxdb-client-apis
,即管理 API,用于创建、修改和删除授权、存储桶、任务和其他 InfluxDB 资源yarn add @influxdata/influxdb-client-apis
有关客户端库的更多信息,请参阅 influxdata/influxdb-client-js 仓库。
配置客户端库
InfluxDB 客户端库需要来自您的 InfluxDB 环境的配置属性。通常,您将以下属性作为应用程序的环境变量提供
INFLUX_URL
INFLUX_TOKEN
INFLUX_ORG
INFLUX_BUCKET
INFLUX_BUCKET_AUTH
Next.js 使用 env
模块为您的应用程序提供环境变量。
./.env.development
文件已进行版本控制,并包含您的开发环境的非机密默认设置。
# .env.development
INFLUX_URL=https://127.0.0.1:8086
INFLUX_BUCKET=iot_center
INFLUX_BUCKET_AUTH=iot_center_devices
要配置未添加到版本控制的密钥和设置,请创建一个 ./.env.local
文件并设置变量 - 例如,设置您的 InfluxDB 令牌和组织
# .env.local
# INFLUX_TOKEN
# InfluxDB API token used by the application server to send requests to InfluxDB.
# For convenience in development, use an **All Access** token.
INFLUX_TOKEN=29Xx1KH9VkASPR2DSfRfFd82OwGD...
# INFLUX_ORG
# InfluxDB organization ID you want to use in development.
INFLUX_ORG=48c88459ee424a04
在您的终端中输入以下命令以重启并加载 .env
文件
CONTROL+C
停止应用程序。yarn dev
启动应用程序。
Next.js 设置了您可以在 process.env
对象中访问的变量 - 例如
console.log(process.env.INFLUX_ORG)
构建 API
您的应用程序 API 提供服务器端 HTTP 端点,用于处理来自 UI 的请求。每个 API 端点负责以下操作
- 监听 HTTP 请求(来自 UI)。
- 将请求转换为 InfluxDB API 请求。
- 处理 InfluxDB API 响应并处理错误。
- 使用状态和数据(对于 UI)进行响应。
创建 API 以列出设备
添加 /api/devices
API 端点,该端点检索、处理和列出设备。/api/devices
使用 /api/v2/query
InfluxDB API 端点在 INFLUX_BUCKET_AUTH
中查询已注册的设备。
处理设备信息请求
创建一个
./pages/api/devices/[[...deviceParams]].js
文件来处理对/api/devices
和/api/devices/<deviceId>/measurements/
的请求。在该文件中,导出一个 Next.js 请求
handler
函数。请参阅示例。
在 Next.js 中,文件名模式 [[...param]].js
创建一个捕获所有 API 路由。要了解更多信息,请参阅 Next.js 动态 API 路由。
检索和列出设备
在 INFLUX_BUCKET_AUTH
中检索已注册的设备并处理查询结果。
创建一个 Flux 查询,该查询获取每个包含
deviceauth
测量值的序列的最后一行。以下示例查询返回包含key
字段(授权 ID)的行,并排除包含token
字段的行(以避免将令牌暴露给 UI)。// Flux query finds devices from(bucket:`${INFLUX_BUCKET_AUTH}`) |> range(start: 0) |> filter(fn: (r) => r._measurement == "deviceauth" and r._field != "token") |> last()
使用
QueryApi
客户端将 Flux 查询发送到POST /api/v2/query
InfluxDB API 端点。
创建一个 ./pages/api/devices/_devices.js
文件,其中包含以下内容
import { InfluxDB } from '@influxdata/influxdb-client'
import { flux } from '@influxdata/influxdb-client'
const INFLUX_ORG = process.env.INFLUX_ORG
const INFLUX_BUCKET_AUTH = process.env.INFLUX_BUCKET_AUTH
const influxdb = new InfluxDB({url: process.env.INFLUX_URL, token: process.env.INFLUX_TOKEN})
/**
* Gets devices or a particular device when deviceId is specified. Tokens
* are not returned unless deviceId is specified. It can also return devices
* with empty/unknown key, such devices can be ignored (InfluxDB authorization is not associated).
* @param deviceId optional deviceId
* @returns promise with an Record<deviceId, {deviceId, createdAt, updatedAt, key, token}>.
*/
export async function getDevices(deviceId) {
const queryApi = influxdb.getQueryApi(INFLUX_ORG)
const deviceFilter =
deviceId !== undefined
? flux` and r.deviceId == "${deviceId}"`
: flux` and r._field != "token"`
const fluxQuery = flux`from(bucket:${INFLUX_BUCKET_AUTH})
|> range(start: 0)
|> filter(fn: (r) => r._measurement == "deviceauth"${deviceFilter})
|> last()`
const devices = {}
return await new Promise((resolve, reject) => {
queryApi.queryRows(fluxQuery, {
next(row, tableMeta) {
const o = tableMeta.toObject(row)
const deviceId = o.deviceId
if (!deviceId) {
return
}
const device = devices[deviceId] || (devices[deviceId] = {deviceId})
device[o._field] = o._value
if (!device.updatedAt || device.updatedAt < o._time) {
device.updatedAt = o._time
}
},
error: reject,
complete() {
resolve(devices)
},
})
})
}
_devices
模块导出一个 getDevices(deviceId)
函数,该函数查询已注册的设备,处理数据,并返回一个包含结果的 Promise。如果您将该函数作为 getDevices()
(不带 deviceId
)调用,它将检索所有 deviceauth
数据点,并返回一个包含 { DEVICE_ID: ROW_DATA }
的 Promise。
为了发送查询并处理结果,getDevices(deviceId)
函数使用 QueryAPI queryRows(query, consumer)
方法。queryRows
执行 query
并将带注释的 CSV 结果作为 Observable 提供给 consumer
。queryRows
具有以下 TypeScript 签名
queryRows(
query: string | ParameterizedQuery,
consumer: FluxResultObserver<string[]>
): void
您提供的 consumer
必须实现 FluxResultObserver
接口,并提供以下回调函数
next(row, tableMeta)
:处理下一行和表格元数据 - 例如,准备响应。error(error)
:接收和处理错误 - 例如,通过拒绝 Promise。complete()
:当所有行都已使用完时发出信号 - 例如,通过解析 Promise。
要了解有关 Observers 的更多信息,请参阅 RxJS 指南。
创建 API 以注册设备
在此应用程序中,已注册设备是一个包含您的设备 ID、授权 ID 和 API 令牌的数据点。API 令牌和授权权限允许设备查询和写入 INFLUX_BUCKET
。在本节中,您将添加 API 端点,该端点处理来自 UI 的请求,在 InfluxDB 中创建授权,并将已注册的设备写入 INFLUX_BUCKET_AUTH
存储桶。要了解有关 API 令牌和授权的更多信息,请参阅 管理 API 令牌
应用程序 API 使用以下 /api/v2
InfluxDB API 端点
POST /api/v2/query
:在INFLUX_BUCKET_AUTH
中查询已注册的设备。GET /api/v2/buckets
:获取INFLUX_BUCKET
的存储桶 ID。POST /api/v2/authorizations
:为设备创建授权。POST /api/v2/write
:将设备授权写入INFLUX_BUCKET_AUTH
。
添加一个
./pages/api/devices/create.js
文件来处理对/api/devices/create
的请求。在该文件中,导出一个 Next.js 请求
handler
函数,该函数执行以下操作- 接受请求正文中的设备 ID。
- 查询
INFLUX_BUCKET_AUTH
,如果设备存在授权,则响应错误。 - 为设备创建授权.
- 将设备 ID 和授权写入
INFLUX_BUCKET_AUTH
. - 当写入请求完成时,响应
HTTP 200
。
为设备创建授权
在本节中,您将创建一个具有对 INFLUX_BUCKET
的读-写权限的授权,并接收设备的 API 令牌。以下示例使用以下步骤创建授权
- 使用配置实例化
AuthorizationsAPI
客户端和BucketsAPI
客户端。 - 检索存储桶 ID。
- 使用客户端库向
/api/v2/authorizations
InfluxDB API 端点发送POST
请求。
在 ./api/devices/create.js
中,添加以下 createAuthorization(deviceId)
函数
import { InfluxDB } from '@influxdata/influxdb-client'
import { getDevices } from './_devices'
import { AuthorizationsAPI, BucketsAPI } from '@influxdata/influxdb-client-apis'
import { Point } from '@influxdata/influxdb-client'
const INFLUX_ORG = process.env.INFLUX_ORG
const INFLUX_BUCKET_AUTH = process.env.INFLUX_BUCKET_AUTH
const INFLUX_BUCKET = process.env.INFLUX_BUCKET
const influxdb = new InfluxDB({url: process.env.INFLUX_URL, token: process.env.INFLUX_TOKEN})
/**
* Creates an authorization for a supplied deviceId
* @param {string} deviceId client identifier
* @returns {import('@influxdata/influxdb-client-apis').Authorization} promise with authorization or an error
*/
async function createAuthorization(deviceId) {
const authorizationsAPI = new AuthorizationsAPI(influxdb)
const bucketsAPI = new BucketsAPI(influxdb)
const DESC_PREFIX = 'IoTCenterDevice: '
const buckets = await bucketsAPI.getBuckets({name: INFLUX_BUCKET, orgID: INFLUX_ORG})
const bucketId = buckets.buckets[0]?.id
return await authorizationsAPI.postAuthorizations(
{
body: {
orgID: INFLUX_ORG,
description: DESC_PREFIX + deviceId,
permissions: [
{
action: 'read',
resource: {type: 'buckets', id: bucketId, orgID: INFLUX_ORG},
},
{
action: 'write',
resource: {type: 'buckets', id: bucketId, orgID: INFLUX_ORG},
},
],
},
}
)
}
要创建对 INFLUX_BUCKET
具有读-写权限的授权,您需要存储桶 ID。为了检索存储桶 ID,createAuthorization(deviceId)
调用 BucketsAPI getBuckets
函数,该函数向 /api/v2/buckets
InfluxDB API 端点发送 GET
请求。然后 createAuthorization(deviceId)
在请求正文中传递一个新的授权,其中包含以下内容
- 存储桶 ID。
- 组织 ID。
- 描述:
IoTCenterDevice: DEVICE_ID
。 - 存储桶的权限列表。
要了解有关 API 令牌和授权的更多信息,请参阅 管理 API 令牌。
接下来,将设备授权写入存储桶。
将设备授权写入存储桶
在 InfluxDB 中完成设备授权后,将设备和授权详情的数据点写入 INFLUX_BUCKET_AUTH
。将设备授权存储在存储桶中,您可以执行以下操作:
- 报告设备授权历史记录。
- 管理带令牌和不带令牌的设备。
- 将同一令牌分配给多个设备。
- 刷新令牌。
要将数据点写入 InfluxDB,请使用 InfluxDB 客户端库向 /api/v2/write
InfluxDB API 端点发送 POST
请求。在 ./pages/api/devices/create.js
中,添加以下 createDevice(deviceId)
函数:
/** Creates an authorization for a deviceId and writes it to a bucket */
async function createDevice(deviceId) {
let device = (await getDevices(deviceId)) || {}
let authorizationValid = !!Object.values(device)[0]?.key
if(authorizationValid) {
console.log(JSON.stringify(device))
return Promise.reject('This device ID is already registered and has an authorization.')
} else {
console.log(`createDeviceAuthorization: deviceId=${deviceId}`)
const authorization = await createAuthorization(deviceId)
const writeApi = influxdb.getWriteApi(INFLUX_ORG, INFLUX_BUCKET_AUTH, 'ms', {
batchSize: 2,
})
const point = new Point('deviceauth')
.tag('deviceId', deviceId)
.stringField('key', authorization.id)
.stringField('token', authorization.token)
writeApi.writePoint(point)
await writeApi.close()
return
}
}
createDevice(device_id)
接受一个 device_id
,并执行以下步骤将数据写入 INFLUX_BUCKET_AUTH
:
- 使用配置中的
url
、token
和org
值初始化InfluxDBClient()
。 - 初始化一个
WriteAPI
客户端,用于将数据写入 InfluxDB 存储桶。 - 创建一个
Point
。 - 使用
writeApi.writePoint(point)
将Point
写入存储桶。
该函数写入一个包含以下元素的数据点:
元素 | 名称 | 值 |
---|---|---|
measurement | deviceauth | |
tag | deviceId | 设备 ID |
field | key | 授权 ID |
field | token | 授权 (API) 令牌 |
安装并运行 UI
influxdata/iot-api-ui
是一个独立的 Next.js React UI,它使用您的应用程序 API 在 InfluxDB 中写入和查询数据。iot-api-ui
使用 Next.js 重写 将 /api/
路径中的所有请求路由到您的 API。
要安装和运行 UI,请执行以下操作:
在您的
~/iot-api-apps
目录中,克隆influxdata/iot-api-ui
仓库 并进入iot-api-ui
目录——例如:cd ~/iot-api-apps git clone git@github.com:influxdata/iot-api-ui.git cd ./iot-app-ui
./.env.development
文件包含默认配置设置,您可以编辑或覆盖这些设置(使用./.env.local
文件)。要启动 UI,请在终端中输入以下命令:
yarn dev
要查看设备列表和注册设备,请在浏览器中访问 https://127.0.0.1:3000/devices。
要了解有关 UI 组件的更多信息,请参阅 influxdata/iot-api-ui
。
此页面是否对您有帮助?
感谢您的反馈!