常田です

API管理機能について

まだ実験段階ですがOpenWhiskにAPI管理の機能がつきました。既にBluemixでも利用可能になっていますのでご紹介します。
これまでもOpenWhiskのActionにはRESTのエンドポイントがついていたのですがこれはGetメソッドのみが利用できました。今回のAPI Gatewayの機能を利用することでこのあたりが整理することが出来ます。

最終的な状態の例を先に示しておきます。

Action Verb API Name URL
/atg_tokida/getBooks get my books https://ac922fa0.api-gw.mybluemix.net/my/books
/atg_tokida/books/create-document post my books https://ac922fa0.api-gw.mybluemix.net/my/books

如何でしょう?すでにAPIを使われている方には非常に嬉しい機能であると理解してもらえるかと思います。
この文章の作成に際しては https://github.com/openwhisk/openwhisk/blob/master/docs/apigateway.md を補足する形で記載しています。不明な点があればドキュメントに戻り目を通してください。

事前の準備

wskコマンドについて

wskコマンドは最新である必要があります。古い場合にはダウンロードをし直してください。

$ wsk property get
whisk auth      367d53...
whisk API host      openwhisk.ng.bluemix.net
whisk API version   v1
whisk namespace     _
whisk CLI version   2016-12-13T10:40:19+00:00
whisk API build     2016-12-13T10:49:44Z
whisk API build number  whisk-build-2366

Actionの用意

早速サンプルを作ってみたいと思います。
ここでは2つのActionを利用してそのActionに対してAPIを作ってみたいと思います。

Action Name 内容
/atg_tokida/getBooks Cloudantに格納されているBook情報を取得します
/atg_tokida/books/create-document Cloudantにデータを格納します

getBooksについてはCloudant側にViewを用意しています。そして docid:data, viewname: lists にたいして Cloudantパッケージの/atg_tokida/books/exec-query-viewを実行しています。

{
  "_id": "_design/data",
  "_rev": "1-a74e2b4963c43b922b401253a790a6e7",
  "views": {
    "lists": {
      "map": "function (doc) {\n  emit( doc._id, {name: doc.name, price:doc.price});\n}"
    }
  },
  "language": "javascript"
}

二つ目に至ってはCloudantパッケージをBindしただけのものです。
それぞれwskで実行してみると以下のような動きになります。

文書の作成

$ wsk action invoke -r -b /atg_tokida/books/create-document -p doc '{"name":"test01", "price":100}'
{
    "id": "196caec5e2e39577406d7d5069e08db0",
    "ok": true,
    "rev": "1-58107783e8f21366b7a39f4b285f9853"
}

文書の表示

$ wsk action invoke -b -r /atg_tokida/getBooks
{
    "offset": 0,
    "rows": [
        {
            "id": "196caec5e2e39577406d7d5069e08db0",
            "key": "196caec5e2e39577406d7d5069e08db0",
            "value": {
                "name": "test01",
                "price": 100
            }
        },
(以下省略)

APIを作る

名前空間としては /my/books を作りたいと思います。このbooksに対してgetすれば一覧を取得してpostすれば追加できるようにしてみます。

作成

GETメソッドの作成

$ wsk api-experimental create -n "my books" /my /books get /atg_tokida/getBooks
ok: created API /my/books GET for action /atg_tokida/getBooks
https://ac922fa0.api-gw.mybluemix.net/my/books

POSTメソッドの作成

$ wsk api-experimental create /my /books post /atg_tokida/books/create-document
ok: created API /my/books POST for action /atg_tokida/books/create-document
https://ac922fa0.api-gw.mybluemix.net/my/books

確認

$ wsk api-experimental list
ok: APIs
Action                            Verb             API Name  URL
/atg_tokida/getBooks               get             my books  https://ac922fa0.api-gw.mybluemix.net/my/books
/atg_tokida/books/create-document    post             my books  https://ac922fa0.api-gw.mybluemix.net/my/books

APIを使ってみる

さっそくcurlコマンドで利用してみます。

$curl -H "Accept: application/json" -H "Content-type: application/json" -X POST -d '{"doc": {"name":"GoodBook","price":10000}}' https://ac922fa0.api-gw.mybluemix.net/my/books
{
  "ok": true,
  "id": "2910a6da279873691430e51b2d8542de",
  "rev": "1-7f83cb6ea4405c25e8168c030b79da24"
}

入りましたのでGETしてみましょう。

curl -X GET https://ac922fa0.api-gw.mybluemix.net/my/books
{
  "total_rows": 6,
  "offset": 0,
  "rows": [{
    "id": "196caec5e2e39577406d7d5069e08db0",
    "key": "196caec5e2e39577406d7d5069e08db0",
    "value": {
      "name": "test01",
      "price": 100
    }
  }, {
    "id": "2910a6da279873691430e51b2d8542de",
    "key": "2910a6da279873691430e51b2d8542de",
    "value": {
      "name": "GoodBook",
      "price": 10000
    }
  },
(以下省略)

出来ましたね。
他にもgetコマンドを実行すると swagger型式でapiが取得できます。

$ wsk api-experimental get /my
{
    "swagger": "2.0",
    "basePath": "/my",
    "info": {
        "title": "my books",
        "version": "1.0.0"
    },
    "paths": {
        "/books": {
            "get": {
                "responses": {
                    "default": {
                        "description": "Default response"
                    }
                },
                "x-ibm-op-ext": {
                    "actionName": "getBooks",
                    "actionNamespace": "atg_tokida",
                    "backendMethod": "POST",
                    "backendUrl": "https://openwhisk.ng.bluemix.net/api/v1/namespaces/atg_tokida/actions/getBooks",
                    "policies": [
(以下省略)

まとめ

如何でしょうか。
この機能を使えばActionをAPIとしてマッピングすることが可能になります。OpenWhiskのActionにつくREST APIだけではできなかったGET/POST/DELETE等のメソッドが利用できるようになりまた管理を行う面でも非常に便利に利用できる機能となります。
実際に公開するためにはこのAPIに対して認証であったりスロットリングであったりと考える必要が出てくる場合には前面に API Connect など配置すると良いでしょう。