IBM Cloud functionsを触ってみた〜その1〜


IBM CloudはWatsonのAPIを使うためだけのクラウドサービスってイメージが強いですが、実際はAWSやGCPのようにDBやアプリを動かすためのサーバーも提供されており、IBM Cloudだけでwebサービスをつくるなんてことも可能です。そしてAWSのlambdaのようなサーバーレス実行環境も存在します。その名も「IBM Cloud functions」。というわけで今回はこのIBM Cloud Functionsを使っていろいろ遊んでみようと思います。

IBM Cloud Functionsって何?

IBM Cloudで提供されているFunction as a Service(FaaS)のことです。Functionを実行するためのイベント(トリガー)が発生してからサーバーが立ち上がって、コードが実行されてサーバーが止まるまでの時間が動作時間として計算される仕組みになっています。もともとはApache OpenWhiskとして提供されていたようですが、2017年8月にIBM Cloud Functionsに名称変更されたようですが大きな仕様変更は無さそうです。標準ではNode.js, python, Ruby, Swift, PHP, Goが対応しています。それ以外の言語はdockerで構築した環境をデプロイすることで動作できるそうです。ちなみにライトプランでも使えます。

とりあえず動かしてみた

まずはお約束のHello Worldをやってみます。ダッシュボードを開いたらメニュー(左上の三本線)を開き、そこからfunctionsを開きます。

「作業の開始」をクリックし、そこからアクションを作成します。ここで言うアクションがFunctionのコードのことです。ということで「Create Action」をクリックします。

すると、新しいアクションの設定画面に移りますので、Function名と言語を定義します。今回はpython3を選択しています。

Createをクリックすると、以下のようにコードエディタのある画面が表示されます。

中にはたった3行のコードが最初から書かれています。まずはシンプルにこのコードを実行してみます。Invokeをクリックしてみると右側に以下のような実行結果が出力されます。

Logsには何も表示されていませんが、コードの中にあるprintの出力やエラーがここに表示されます。デバッグに使えますね。

REST APIで動かしてみる

では、今度はREST API的な使い方をやってみます。左側のメニューから「Endpoints」を選択してエンドポイントの情報を表示させます。その後、下の方にあるCURLの情報があるので、右端の書類のアイコンをクリックしてCurlコマンドをコピーします。ちなみにAPI-KEYの部分にはすでにAPIキーが入っているのでターミナル上でそのままコピーしたコマンドを実行できるようになっています。

Curlを実行すると、以下のようなjsonが出力されます。

{
  "activationId": "698e86c70a5f40bb8e86c70a5f50bbfd",
  "annotations": [
    {
      "key": "path",
      "value": "[email protected]_dev/kmiuraHelloWorld"
    },
    {
      "key": "waitTime",
      "value": 42
    },
    {
      "key": "kind",
      "value": "python:3.7"
    },
    {
      "key": "timeout",
      "value": false
    },
    {
      "key": "limits",
      "value": {
        "concurrency": 1,
        "logs": 10,
        "memory": 256,
        "timeout": 60000
      }
    }
  ],
  "duration": 2,
  "end": 1569937475019,
  "logs": [],
  "name": "kmiuraHelloWorld",
  "namespace": "YOUR_NAMESPACE",
  "publish": false,
  "response": {
    "result": {
      "message": "Hello world"
    },
    "status": "success",
    "success": true
  },
  "start": 1569937475017,
  "subject": "YOUR_MAIL",
  "version": "0.0.1"
}

なにか通知してみる

LINE Notifyのアクセストークンを発行する

せっかくなので何か通知をするアクションを作成してみます。そこで、LINE Notifyを使います。こちらからログインして、アカウント名→マイページを開きます。

マイページの下にある「トークンを発行する」をクリックして、Notify用のトークン名を設定し、「1:1でLINE Notifyから通知を受け取る」を選択してトークンを発行してください。

※発行されたトークンは発行画面を閉じると2度と確認することが出来ないので忘れずにコピーしておきます。


IBM Cloud Functionsでの設定

もう1度Cloud Functionsに戻って先程コピーしたアクセストークンを記入します。コードに直接書く方法もありますが、今回は「Parameters」に変数を定義してみます。今回はParameter NameにはAPI_TOKENを、Parameter Valueには先程コピーしたアクセストークンを記入します。このとき、アクセストークンは必ずダブルクオーテーションで囲みます。

ここで定義した値はコード上では、dict["ACCESS_TOKEN"]で呼び出すことが出来ます。以上を踏まえて、LINE Notifyに通知するコードを足したコードが以下に示すものになります。

ソースコード

#
#
# main() will be run when you invoke this action
#
# @param Cloud Functions actions accept a single parameter, which must be a JSON object.
#
# @return The output of this action, which must be a JSON object.
#
#
import sys
import json
import requests

def main(dict):
    # set Value
    access_token = dict["ACCESS_TOKEN"]
    url = 'https://notify-api.line.me/api/notify'
    headers = {
        'Authorization': 'Bearer {}'.format(access_token),
    }
    payload = {
        'message': 'Hello World',
    }

    # request Notify
    response = requests.post(url, headers=headers, params=payload)
    res = json.loads(response.text)
    print(res)

    return { 'message': res["message"] }

動作確認

エディタのコードを上記に置き換えて、右上にあるSaveをクリックしてからInvokeをクリックして実行します。すると、以下のようにメッセージが表示されれば、成功です。

IBM Cloud Functionsを使えば、サーバの保守を気にすることなく作りたい機能を実装出来てしまうので魅力的だと思いますが、動作が遅かったりデメリットもあったのでそこは次回また詳しく掘り下げた後にまとめようと思います。
その2はこちら