文档文档

JavaScript 客户端库入门

按照此分步教程,使用 InfluxData 客户端库和您最喜欢的框架或语言构建物联网 (IoT) 应用程序。

在本教程中,您将使用 InfluxDB API 和客户端库构建现代应用程序,并学习以下内容

  • InfluxDB 核心概念。
  • 应用程序如何与设备和 InfluxDB 交互。
  • 如何对应用和设备进行 API 身份验证。
  • 如何安装客户端库。
  • 如何在 InfluxDB 中写入和查询数据。

目录

设置 InfluxDB

如果您尚未执行此操作,请创建 InfluxDB Cloud 帐户安装 InfluxDB OSS

IoT Starter 示例应用假定以下先决条件

  • InfluxDB org 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 应用程序

  1. 在您的 ~/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"
    
  2. 安装完成后,在终端中输入以下命令以进入您的 ./iot-api-js 目录并启动开发服务器

    cd iot-api-js
    yarn dev -p 3001
    

要查看应用程序,请在浏览器中访问 http://localhost:3001

安装 InfluxDB 客户端库

InfluxDB 客户端库提供以下 InfluxDB API 交互

  • 使用 Flux 语言查询数据。
  • 将数据写入 InfluxDB。
  • 在后台批量处理数据。
  • 在失败时自动重试请求。
  1. 在终端中输入以下命令以安装客户端库

    yarn add @influxdata/influxdb-client
    
  2. 在终端中输入以下命令以安装 @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=http://localhost: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 文件

  1. CONTROL+C 停止应用程序。
  2. yarn dev 启动应用程序。

Next.js 设置您可以在 process.env 对象中访问的变量——例如

console.log(process.env.INFLUX_ORG)

构建 API

您的应用程序 API 提供服务器端 HTTP 端点,用于处理来自 UI 的请求。每个 API 端点负责以下操作

  1. 监听 HTTP 请求(来自 UI)。
  2. 将请求转换为 InfluxDB API 请求。
  3. 处理 InfluxDB API 响应并处理错误。
  4. 使用状态和数据(对于 UI)进行响应。

创建 API 以列出设备

添加 /api/devices API 端点,该端点检索、处理和列出设备。/api/devices 使用 /api/v2/query InfluxDB API 端点查询 INFLUX_BUCKET_AUTH 以查找已注册的设备。

处理设备信息请求

  1. 创建 ./pages/api/devices/[[...deviceParams]].js 文件以处理对 /api/devices/api/devices/<deviceId>/measurements/ 的请求。

  2. 在该文件中,导出 Next.js 请求 handler 函数。请参阅示例

在 Next.js 中,文件名模式 [[...param]].js 创建一个捕获所有 API 路由。要了解更多信息,请参阅 Next.js 动态 API 路由

检索和列出设备

INFLUX_BUCKET_AUTH 中检索已注册的设备并处理查询结果。

  1. 创建一个 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()
    
  2. 使用 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 提供给 consumerqueryRows 具有以下 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
  1. 添加 ./pages/api/devices/create.js 文件以处理对 /api/devices/create 的请求。

  2. 在该文件中,导出执行以下操作的 Next.js 请求 handler 函数

    1. 接受请求正文中的设备 ID。
    2. 查询 INFLUX_BUCKET_AUTH,如果设备存在授权,则响应错误。
    3. 为设备创建授权.
    4. 将设备 ID 和授权写入 INFLUX_BUCKET_AUTH.
    5. 写入请求完成时,响应 HTTP 200

请参阅示例.

为设备创建授权

在本节中,您将创建一个具有对 INFLUX_BUCKET-权限的授权,并接收设备的 API 令牌。以下示例使用以下步骤创建授权

  1. 使用配置实例化 AuthorizationsAPI 客户端和 BucketsAPI 客户端。
  2. 检索存储桶 ID。
  3. 使用客户端库向 /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

  1. 使用来自配置的 urltokenorg 值初始化 InfluxDBClient()
  2. 初始化 WriteAPI 客户端以将数据写入 InfluxDB 存储桶。
  3. 创建 Point
  4. 使用 writeApi.writePoint(point)Point 写入存储桶。

该函数写入具有以下元素的点

元素名称
测量设备认证
标签设备ID设备 ID
字段授权 ID
字段令牌授权 (API) 令牌

安装并运行 UI

influxdata/iot-api-ui 是一个独立的 Next.js React UI,它使用您的应用程序 API 在 InfluxDB 中写入和查询数据。iot-api-ui 使用 Next.js rewrites/api/ 路径中的所有请求路由到您的 API。

要安装和运行 UI,请执行以下操作

  1. 在您的 ~/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
    
  2. ./.env.development 文件包含您可以编辑或覆盖的默认配置设置(使用 ./.env.local 文件)。

  3. 要启动 UI,请在您的终端中输入以下命令

    yarn dev
    

    要查看设备列表和注册设备,请在浏览器中访问 http://localhost:3000/devices

要了解有关 UI 组件的更多信息,请参阅 influxdata/iot-api-ui


此页面是否对您有帮助?

感谢您的反馈!


Flux 的未来

Flux 即将进入维护模式。您可以继续像现在这样使用它,而无需对您的代码进行任何更改。

阅读更多

现已全面上市

InfluxDB 3 Core 和 Enterprise

快速启动。更快扩展。

获取更新

InfluxDB 3 Core 是一个开源、高速、近实时数据引擎,可实时收集和处理数据,并将其持久化到本地磁盘或对象存储。InfluxDB 3 Enterprise 构建在 Core 的基础上,增加了高可用性、读取副本、增强的安全性以及用于更快查询和优化存储的数据压缩。InfluxDB 3 Enterprise 的免费层级可供非商业家用或业余爱好者使用。

有关更多信息,请查看