Serve the API

With our back end functionality defined, it’s time to actually serve the API. The code in apis/index.js defines the REST HTTP endpoints for the IoT Center API. Express.js routing1 is used in conjunction with the helper functions documented above.

In the following import statements, functions imported from authorizations.js, and env.js (covered above):

const env = require('../env')
// const {stringify} = require('yaml')
const {
  getIoTAuthorization,
  createIoTAuthorization,
  getIoTAuthorizations,
  getDeviceId,
  deleteAuthorization,
} = require('../influxdb/authorizations')

(Source)

We also need to import the Router() method from Express, in order to serve the REST API. Do this by adding:

const express = require('express')
const router = express.Router()

API paths

Express handles HTTP verbs and paths.

We need our server to:

  • register new devices
  • return information about current devices
  • list all register devices
  • delete device registrations

We can accomplish this using three API endpoints: a GET /env/:deviceId, a GET /devices; DELETE /devices/:deviceId

Describe or register device

GET /env/:deviceId

Return environment for a specific device by its ID.

This will either run createIoTAuthorization if none exists, or getIoTAuthorization. It also handles registration.

router.get(
  '/env/:deviceId',
  handleError(async (req, res) => {
    const deviceId = req.params.deviceId
    let authorization = await getIoTAuthorization(deviceId)
    let registered = false
    if (!authorization) {
      if (req.query.register !== 'false') {
        authorization = await createIoTAuthorization(deviceId)
        registered = true
      } else {
        res.status(403)
        return res.json({
          id: deviceId,
          registered,
        })
      }
    }
    [*snip*]
  })
)

(Source)

This creates an authorization if it doesn’t exist:

if (req.query.register !== 'false') {
  authorization = await createIoTAuthorization(deviceId)
  registered = true

List devices

GET /devices

Gets a list of registered devices used in web UI to provide a list devices. It contains deviceId.

router.get(
  '/devices',
  handleError(async (_req, res) => {
    const authorizations = await getIoTAuthorizations()
    res.json(
      authorizations.map((a) => ({
        key: a.id,
        deviceId: getDeviceId(a),
        createdAt: a.createdAt,
      }))
    )
  })
)

(Source)

Delete device

DELETE /devices/:deviceId

Remove a device identified by device_id. It also deletes the associated authorization token from InfluxDB.

router.delete(
  '/devices/:deviceId',
  handleError(async (req, res) => {
    const deviceId = req.params.deviceId
    const authorizations = await getIoTAuthorizations()
    for (const a of authorizations) {
      if (getDeviceId(a) === deviceId) {
        await deleteAuthorization(a.id)
        res.status(204)
        res.send('Device authorization removed')
        return
      }
    }
    res.status(404)
    res.send(`Device ${deviceId} not found!`)
  })
)

(Source)

1

For more information on routing in Express, see Basic routing and Routing