AsyncAPIでつくるMQTTインターフェイス仕様書!

2018.10.29

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

お疲れさまです。サーバーレス開発部の新井です。

今回は、MQTTのインターフェース仕様書を作成するツールAsyncAPIに関する記事です。 弊社岩田のブログでも促されたので頑張って書いていこうかと思います。

背景

最近はAWS IoT案件に携わる機会が多く、デバイスの開発者とMQTTのトピックやパラメータの設計をやり取りする機会が増えています。

で、ここのインターフェイスを統一的に管理したいというのがあり、Swaggerみたいな規定フォーマットに沿って記入すればドキュメント作成してくれるようなツールを探したところ、AsyncAPIなるものがあったので、今回はこちらを紹介していきます。

ソースはYAMLで作成して、フォーマットに沿って入力していけば、最終的には上記の様にHTMLファイルベースのドキュメントを生成してくれます。また、MQTTのPub/Subを実行するコードを生成してくれたりする機能もあり、とても便利なツールです。

ということで、今回はチュートリアルを交えて紹介していきます。

チュートリアルをやってみる

私の方でいくつかのパートに分けてみました。

1. エディタで編集してみる

こちらのオンラインエディタに以下のサンプルを貼り付けてみてください。

サンプルソースをコピペ

asyncapi: '1.0.0'
info:
  title: Streetlights API
  version: '1.0.0'
  description: |
    The Smartylighting Streetlights API allows you
    to remotely manage the city lights.
  license:
    name: Apache 2.0
    url: 'https://www.apache.org/licenses/LICENSE-2.0'
baseTopic: smartylighting.streetlights.1.0
servers:
  - url: api.streetlights.smartylighting.com:{port}
    scheme: mqtt
    description: Test broker
    variables:
      port:
        description: Secure connection (TLS) is available through port 8883.
        default: '1883'
        enum:
          - '1883'
          - '8883'
topics:
  event.{streetlightId}.lighting.measured:
    publish:
      $ref: '#/components/messages/lightMeasured'
components:
  messages:
    lightMeasured:
      summary: Inform about environmental lighting conditions for a particular streetlight.
      payload:
        type: object
        properties:
          lumens:
            type: integer
            minimum: 0
            description: Light intensity measured in lumens.
          sentAt:
            $ref: "#/components/schemas/sentAt"
  schemas:
    sentAt:
      type: string
      format: date-time
      description: Date and time when the message was sent.

ソースの構成は大きく分けて

  • asyncapi
    • asyncapiのバージョン情報を記載
  • info
    • タイトルやバージョンなど全体の概要の記載
  • servers
    • urlやportなど接続先のサーバー情報の記載
  • topics
    • mqttのトピック名、Pub/Subを記載
  • components
    • messagesには、Pub/Subするメッセージの詳細を記載 (主にtopicsから参照される)
    • schemasには、メッセージ内のパラメータの詳細を記載 (主にmessagesから参照される)

が用意されていているので必要に応じて埋めていってください。

細かいフォーマットやスキーマはThe specificationで確認できます。

schemasexampleなんかも記入できるので、ココらへん埋めていけば仕様書としてはよりわかりやすくなるかと思います。

2. HTMLファイルベースのドキュメントを作成してみる

オンラインエディタ右上のDownload docsからも行えますが、ここではローカル実行するためのツールを使って行っていきます。

まずは、フォルダ作成

mkdir streetlights && cd "$_"

空のファイルを作成

touch asyncapi.yml

ファイルの中身に作成したソースコードを貼り付け

ドキュメント作成用のパッケージインストール

npm install -g asyncapi-docgen

ドキュメント生成

adg asyncapi.yml -o ./docs

docs以下に、index.htmlが作成されているかと思います。

$ tree -L 2
.
├── asyncapi.yml
└── docs
    ├── css
    └── index.html

3. Node.jsベースのコードを自動生成してPub/Subしてみる

次に作成したMQTTインターフェース仕様書に沿ってNode.jsでコードを生成してみます。

編集ができたら、ソースコードを生成するためのパッケージをインストール

npm install -g asyncapi-node-codegen

次に、コード生成

anc asyncapi.yml -o ./my-api

my-api以下に、ソースファイルが生成されているかと思います。

$ tree -L 2
.
├── asyncapi.yml
├── docs
│   ├── css
│   └── index.html
└── my-api
    ├── config
    ├── Dockerfile
    ├── package.json
    ├── README.md
    └── src

関連パッケージのインストール

pakcage.jsonhermesjs-mqttのバージョンを1.xに修正する必要ありました。Do not use latest

cd my-api
npm install

config/common.ymlhost_urltopicsを下記に変更

default:
  broker:
    mqtt:
      host_url: mqtt://test.mosquitto.org
      topics: smartylighting/streetlights/1/0/event/#
      qos:
      protocol: mqtt
      retain:

実行

$ npm start

> streetlights_api@1.0.0 start /streetlights/my-api
> node src/api/index.js

MQTT adapter is listening...

起動しましたね。

では次に、別のターミナルからMQTTのPub/Subを実行するパッケージのインストール

npm install mqtt -g

Publishしてみる

mqtt pub -t 'smartylighting/streetlights/1/0/event/farolina/lighting/measured' -h 'test.mosquitto.org' -m '{"lumens": 3, "sentAt": "2017-06-07T12:34:32.000Z"}'

元のターミナルで確認してみる

MQTT adapter is listening...
smartylighting/streetlights/1/0/event/farolina/lighting/measured was received from broker:
{ lumens: 3, sentAt: '2017-06-07T12:34:32.000Z' }

はい、ちゃんとメッセージ届いてますね。

自動生成されたソースコードは作りこんでいけば、もっと色々できそうですね。

以上でチュートリアル終了です。

まとめ

いかがだったでしょうか。

個人的には、今までマークダウンで記載してたMQTTのインターフェース仕様書が統一的に管理できてとてもすっきりしました。マークダウンだと、必要な項目が漏れたり、パラメータを変更するのに複数トピックまたがって修正入れたり、見た目も分かりづらかったり、と色々問題あったのですが、ココらへんが一挙に解決されたのでとても助かってます。

GitHub見る限り、まだ開発中のツールもいくつかあるみたいなので、今後も期待です。特に、エディタに関してはローカルで起動できるようなツールを提供してくれると更に捗りそうです。

以上、お疲れさまでした!