Fn Projectを使用したAPI開発

 2022.10.21  柳瀨正之

先日OCIを利用したサーバレスAPI環境の構築に関しての記事をお送りしましたが、今回はその環境で動かすAPIを開発する際のポイントについての記事をお送りします。

サーバレスAPI環境の構築に関しての記事はこちら
OCIにおけるサーバレスAPI環境の構築方法~第1回~
OCIにおけるサーバレスAPI環境の構築方法~第2回~
OCIにおけるサーバレスAPI環境の構築方法~第3回~
OCIにおけるサーバレスAPI環境の構築方法~第4回~

 

プログラム言語にはPythonを使用しています。

環境構築の中でFn Projectをインストールしてfnコマンドでファンクションを作成した際に次の3つのファイルが生成されたと思います。

  1. func.py
  2. func.yaml
  3. requirements.txt

3 はライブラリを一括インストールする際に使用するファイルです。

既に利用されたことがあると思うので詳しい説明は割愛しますが、デフォルト状態(fnコマンドでファンクションを作成しただけ)では“fdk>=0.1.46”と記載されています。

必要なライブラリはこのファイルに記載してコンテナイメージが作成される際にインストールされるようにします。

2 はファンクションの動作に関する設定が記載されています。

以下はfnコマンドでファンクションを作成された時点での設定になります。

schema_version: 20180708
name: sample
version: 0.0.1
runtime: python
build_image: fnproject/python:3.8-dev
run_image: fnproject/python:3.8
entrypoint: /python/bin/fdk /function/func.py handler
memory: 256

設定に関する説明が記載されたものが見つからなかったので、設定を変更したことはありませんが、コンテナイメージをビルドする度に”version”はカウントアップされます。

開発途中で何度もビルドしていると”version”がとんでもない番号になってしまうので、その際は”version”の行自体を削除してからビルドすると、0.0.1からカウントアップしてくれます。

またデフォルトのプログラム名(func.py)を変更したい場合は” entrypoint””/function/func.py”” func.py”の部分を変更すると良いと思います。

 

いよいよ本題の 1 のfunc.pyの説明に入ります。

デフォルト状態では以下のプログラムが書かれています。

 

■デフォルトのfunc.py

import io
import json
import logging


from fdk import response


def handler(ctx, data: io.BytesIO = None):
   name = "World"
   try:
       body = json.loads(data.getvalue())
       name = body.get("name")
   except (Exception, ValueError) as ex:
       logging.getLogger().info('error parsing json payload: ' + str(ex))
   logging.getLogger().info("Inside Python Hello World function")
   return response.Response(
       ctx, response_data=json.dumps(
           {"Message": "Hello {0}".format(name)}),
       headers={"Content-Type": "application/json"}
   )

 

処理としては、ファンクションが実行されると”func.yaml””entrypoint”で指定された”func.py””handler関数が呼び出されます。

このhandler関数には”ctx”” data”2つの引数が指定されています。

“ctx”にはコンテキストオブジェクトが格納されます。

“data”にはプログラムが受け取ったデータが格納されます。

“ctx”の中身を確認するために”func.py”の実行結果を戻している部分を以下に変更してcurl経由でプログラムを実行します。

 

■変更後

return response.Response(
  ctx, response_data=json.dumps(
      {"Message": "Hello {0}".format(name),
      "ctx.Headers" : ctx.Headers(),
      "ctx.RequestURL": ctx.RequestURL(),
      "ctx.Method": ctx.Method()}),
  headers={"Content-Type": "application/json"}
)

 

実行した結果は以下になります。

 

■実行結果

{
"Message": "Hello None",
"ctx.Headers": {
  "host": "localhost",
  "user-agent": [
    "Go-http-client/1.1",
    "curl/7.61.1"
  ],
  "transfer-encoding": "chunked",
  "content-type": "application/json",
  "fn-call-id": "03N0AG2E0G3HAJ0XF1KT00000D",
  "fn-deadline": "2022-07-07T03:40:18Z",
  "accept": "*/*",
  "content-length": "21",
  "fn-http-method": "POST",
  "fn-http-request-url": "http://localhost:8080/t/test/v1",
  "fn-intent": "httprequest",
  "accept-encoding": "gzip"
},
"ctx.RequestURL": "http://localhost:8080/t/test/v1",
"ctx.Method": "POST"
}

 

ヘッダー、リスエストURL、メソッドを表示させています。

ネットワーク経由で実行すると"ctx.Headers"”x-forwarded”系のデータやリファラーといったデータが入るようになります。

"ctx.RequestURL"にはリクエストのURLが入るのでIDの受け渡しに利用できます。

“ctx.Method”にメソッドが入るので処理分岐で利用できます。

また、これら以外にもOCIで割り当てたユニークIDやファンクションの構成なども取得できます。

 

次にアプリケーションにデータを送って“data”の中身を確認してみます。

サンプルプログラムには既にデータを受け取ってJSONdumpする処理が書かれているので、curlコマンドに項目名を”name”、値を”AAAAA”のデータを付与して実行します。

以下は変化のあった箇所のみを記載しています。

 

■実行結果

"Message": "Hello AAAAA",

 

これでAPIを開発するための準備ができました。

Fn Projectを利用すれば簡単にAPIを開発することができるようになります。

ここで開発したプログラムをコンテナイメージにして、コンテナ・レジストリにプッシュすることでAPIゲートウェイから呼び出すことができます。

 

環境構築、API開発に続き最後の記事ではAPIアクセスを制限するためのAPIゲートウェイの認証について紹介したいと思います。

 

最後までお付き合いいただきありがとうございました。


RECENT POST「OCIで作ってみた」の最新記事


OCIで作ってみた

OCVS・Horizon構築してみた③

OCIで作ってみた

OCVS・Horizon構築してみた②

OCIで作ってみた

OCVS・Horizon構築してみた①

OCIで作ってみた

OCVSにブロック・ボリュームをアタッチして、vSphereのデータストアに追加してみた

Fn Projectを使用したAPI開発