本記事は「Kong Advent Calendar 2024」の11日目のエントリで、API GatewayのKongを体感的に使えるKong Lampを作ってみます
ChatGPT/OpenAI APIに代表されるように、世の中APIの必要性は増すばかり。そんなAPIを統合的に管理するKong API Gatewayの需要が高まってきています。
ここでは、APIがキックされるとRaspberry Piにつないだパトランプがピカピカ光ったり、APIの流量制限などができるKong Patrol Lampを作ります。
この記事で学べる事
A. Kong KonnectでのAPI管理が学べる
B. IoTデバイス(Raspberry Pi)上の公開APIが作れる
C. KongのPlugins、Analyticsの設定方法が分かる
Kong Patrol Lampの作り方はざっとこんな感じ
- Kong API Gatewayの導入
- Raspberry Piとパトランプをつないで光らせる
- パトランプ公開APIの作成
- KongへのAPIの登録とKong Pluginsの設定
- Kong Buttonと連動させて完成!
ハードウェアで必要なもの
必要なもの | 部品 |
---|---|
Raspberry Pi | |
パトランプ | |
トランジスタ | |
その他ジャンパケーブル、両面テープ、など | 適宜 |
こんなふうにKongを通して光ります。
I. Kong API Gatewayの立ち上げ
まだKong環境を用意していない方は、前回記事 と同様のこの流れに従って、KongのSAAS環境Kong Konnectで、API Gatewayを立ち上げて下さい。
1. Kong Konnect にアクセス
https://cloud.konghq.com にアクセスして、ユーザー、パスワードなどを登録し、Kong Konnectに入ります。
2. Control Planeを作成
Konnectにログオンできたら、Gateway Managerスクリーンから New Control Plane を押して、新しいGatewayを作ります。
3. Data Planeを作成
Data Plane Nodesには、Kongのフルマネージド環境の Dedicated Cloud Instances を選びます。
そうすると Payment method の設定を求められるので、クレジットカードの支払い方法をセットします。
(無料枠$500があるので、その範囲内の最小限の使い方なら課金されることはありません)
Regionを選ぶ画面が出るので、USなどの適当なRegionを選びます。
4. (Option) ドメインの設定
(オプションですが)左側メニューのCustom Domainsから、個人のドメイン名を紐づけます。
これでhttps://konnect.example.com のようなURLでKong環境にアクセスできるようになりました。
II. Raspberry Piとパトランプをつないで光らせる
ハードウェアとの連携として、Raspberry Pi(ラズパイ)とパトランプを接続して、外部からピカピカさせるAPIを作成します。
1. ラズパイとパトランプの接続
今回使ったパトランプは、単三電池3本の4.5Vのものでした。間にトランジスタを挟んで、5V電源のオンオフを行います。
トランジスタは平らな面を手前にして、左からE, C, Bとなります。
以下のようにパトランプ、トランジスタ、ラズパイを接続します。
パトランプ側 | トランジスタ | ラズパイ側 |
---|---|---|
- | E (エミッター) | GND (白) |
電源 | C (コレクタ) | - |
- | B (ベース) | GPIO 4 (緑) |
電源 | - | 5V (黄) |
トランジスタとパトランプの接続 | 空中配線で見づらくてスミません。。 |
2. パトピカの確認
ラズパイの接続方法は、このような記事に従って、SSHでアクセスしています。
以下のコマンドから、接続されたパトランプが動くかどうかを確認します。
$ gpio -g mode 4 out
$ gpio -g write 4 1
$ gpio -g write 4 0
まずはコマンドを打って、ラズパイからパトランプを点灯することができました。
III. パトランプAPIの作成
ハードウェアとしての設定ができたので、これをAPIとして実行できるようにします。
1. Expressの導入
ラズパイ上のパトランプを光らせるコマンドを、外部から使えるようにAPI化します。
それにはラズパイにNode.jsとExpressを導入して、Webサーバーを立ち上げます。
以下コマンドでインストールして、Expressのバージョンが確認できたら導入が上手くいっています。
$ sudo apt install -y nodejs npm
$ npm install express --save
$ npm install express-generator -g
$ express --version
このExpressを使って、ラズパイ内にAPIを走らせるための環境を用意します。
$ express iot
$ cd iot
$ npm install
$ npm start
これでExpress Appが立ち上がったので、ラズパイの localhost:3000 にアクセスします。
デフォルトのWelcomebページが立ち上がったら、Expressサーバーが動いています。
2. パトランプAPIの作成
ここからパトランプAPIを作っていきます。
まずiotフォルダ下のapp.jsを開いて、以下Addedの2行を追加します。
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');
var led = require('./routes/led'); // << *** LED API Added ***
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', indexRouter);
app.use('/users', usersRouter);
app.use('/led', led); // << *** LED API added ***
// ...
次にroutesフォルダ下にled.jsファイルを作成して、以下のようなプログラムを作ります。
var express = require('express');
var router = express.Router();
var exec = require('child_process').exec;
exec('gpio -g mode 4 out');
router.get('/:onoff', function(req, res, next) {
var param = {"result":"LED "+ req.params.onoff + " !", "bright":req.query.bright};
res.header('Content-Type', 'application/json; charset=utf-8')
res.send(param);
if ( req.params.onoff == "on" ) {
exec('gpio -g write 4 1');
} else {
exec('gpio -g write 4 0');
}
});
module.exports = router;
これを実行して試してみます。
$ curl localhost:3000/led/on
$ curl localhost:3000/led/off
どうでしょうか?先ほどのコマンドのようにAPIからパトランプが点灯したでしょうか?
3. ngrokによるトンネル化
ラズパイ上のパトランプAPIを、インターネットから使えるようなAPIにします。
それにはngrokというサービスを使用します。
https://ngrok.com にアクセスし、Sign upからユーザーを作成します。
ログオンできたら、Setup IntroductionからRaspberry Piのngrokの導入を行います。
画面上のステップに従って、snapでngrokをインストールします。
$ snap install ngrok
$ ngrok config add-authtoken ngrok_token
$ ngrok http localhost:3000
自動化の設定を行なっておきます。
_IP=$(hostname -I) || true
if [ "$_IP" ]; then
printf "My IP address is %s\n" "$_IP"
fi
sudo -u username /usr/local/nvm/versions/node/v10.0.0/bin/node /usr/local/nvm/versions/node/v10.0.0/bin/forever start -a -d /home/pi/Programs/iot/app.js
exit 0
ngrokによりEndpointが生成されるので、このURL(無料枠だと一つだけ)を保存しておきます。
以下のようにEndpoint(ngrok_endpoint)とExpressサーバー(led.js)を紐付けたシェルプログラムを作っておきます。
#!/bin/bash
ngrok http --domain=ngrok_endpoint localhost:3000
シェルプログラムをラズパイの中で自動起動させておくと、インターネット上からngrokのURLからラズパイのLED APIを起動する事ができるようになります。
IV. パトランプAPIの登録とKong Pluginsの設定
作ったパトランプAPIをKong Konnect上に登録します。Kongの大事な機能、Pluginsも設定します。
1. パトランプAPIをサービスとして登録
Kong Konnectの左側のGateway Servicesから、New Gateway Serviceを選び、新しいサービスを作成します。
先ほどのngrok Endpointをhostに指定します。Pathは先ほど作った/led になります。
次にこのサービスのルートを以下のように作成します。
2. Kongからの接続確認
設定が済んだらコマンドラインからcurlで接続を確認します。
KONGプロキシに設定しているアドレスは、ご自分の独自ドメインかこのKonnectのURLをセットします。
$ KONG=konnect.example.com
$ curl $KONG/led/on
$ curl $KONG/led/off
実行してみます。
Kongのプロキシを使って接続して、resultが出れば正常に接続しています。
またブラウザからも実行してみます。
これによりパトランプが回り始めたらKongへの登録は成功です。
3. Kong Pluginsの設定
KongにはPlug-inを追加するだけで様々な機能を簡単に追加する事ができます。
ここでは流量制限のRate Limit Plug-inを設定してみます。
先ほどのRouteのところからPluginsに移動します。
New Plugin画面から、"Rate Limiting Advanced"を選びます。
Rate Limitのところで、60秒間に10回以上APIが呼ばれた429 Errorを返すように設定します。
ここで先ほどのLED APIを連続してキックしてみます。
そうすると、rate limit exceededのメッセージが出て一時的にAPIがコールできないようになります。
KonnectのAnalytics画面でもそれが確認できます。
V. Kong Buttonと連動させて完成!
前回記事で作成したKong Dash Buttonと連動させて、パトランプを光らせるようにして完成です!
1. Kong Buttonの機能追加
機能としては、長押しすると、赤く光って危険を知らせるので、それに連動してこのパトランプを光らせます。
そのために、前回作った Buttonのスケッチに、以下のように追記します。
(Added部分の追加)
#include "M5StickCPlus.h"
// ...
String led="https://konnect.x.com/led"; // *** Added ***
void http_get(String url){ // *** Added ***
if(WiFi.status() == WL_CONNECTED){ // *** Added ***
Serial.println("Wifi Connected"); // *** Added ***
HTTPClient http; // *** Added ***
http.begin(url); // *** Added ***
int httpCode = http.GET(); // *** Added ***
Serial.println(httpCode); // *** Added ***
if (httpCode == HTTP_CODE_OK) { // *** Added ***
String payload = http.getString(); // *** Added ***
Serial.println(payload); // *** Added ***
} // *** Added ***
http.end(); // *** Added ***
} // *** Added ***
} // *** Added ***
const int longPress_ms = 1200;
void loop(){
M5.update();
// ...
if (M5.BtnA.wasPressed()) {
delay(longPress_ms);
if(M5.BtnA.read() == true){
Serial.print("Red");
M5.Lcd.fillScreen(RED);
M5.Lcd.printf("Help!");
sendLine("問題発生! HELP!", 8522, 16581287);
http_get(led+"/on"); // *** Added ***
delay(500);
} else {
Serial.print("GREEN");
M5.Lcd.fillScreen(GREEN);
M5.Lcd.printf("Home!");
sendLine("元気だよ! HOME!", 8522, 16581271);
http_get(led+"/off"); // *** Added ***
delay(500);
}
}
delay(500);
}
2.全部つなげて使ってみよう!
ユースケースとしては、このボタンをお子さんなどに持っていてもらい、何かあったら長押しすると、家のパトランプが光り警告するというものです。
ボタンを長押しすると、このようにパトランプが光だします。
スマホには「問題発生!HELP!」とメッセージが届いていました!
もう一度、短く押して元気だよを送ると、パトランプは消灯します。
まとめ
という事で、Kong Konnect上にAPIをセットし、ハードウェアのパトランプを光らせる事ができるようになりました。
Kongを使うとさまざまなAPIをまとめて管理でき、またCloud Gatewayを使うと自分自身で環境を持たなくてもフルマネージドな環境が手に入ります。
今後もさまざまなAPIを追加して、便利な環境にしていこうと思います!
それでは、よいKongを! Happy Kong!
ヨシケン