先日OCIを利用したサーバレスAPI環境の構築に関しての記事をお送りしましたが、今回はその環境で動かすAPIを開発する際のポイントについての記事をお送りします。
サーバレスAPI環境の構築に関しての記事はこちら
OCIにおけるサーバレスAPI環境の構築方法~第1回~
OCIにおけるサーバレスAPI環境の構築方法~第2回~
OCIにおけるサーバレスAPI環境の構築方法~第3回~
OCIにおけるサーバレスAPI環境の構築方法~第4回~
プログラム言語にはPythonを使用しています。
環境構築の中でFn Projectをインストールしてfnコマンドでファンクションを作成した際に次の3つのファイルが生成されたと思います。
- func.py
- func.yaml
- 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”の中身を確認してみます。
サンプルプログラムには既にデータを受け取ってJSONにdumpする処理が書かれているので、curlコマンドに項目名を”name”、値を”AAAAA”のデータを付与して実行します。
以下は変化のあった箇所のみを記載しています。
■実行結果
"Message": "Hello AAAAA",
これでAPIを開発するための準備ができました。
Fn Projectを利用すれば簡単にAPIを開発することができるようになります。
ここで開発したプログラムをコンテナイメージにして、コンテナ・レジストリにプッシュすることでAPIゲートウェイから呼び出すことができます。
環境構築、API開発に続き最後の記事ではAPIアクセスを制限するためのAPIゲートウェイの認証について紹介したいと思います。
最後までお付き合いいただきありがとうございました。
- カテゴリ:
- OCIで作ってみた
- Oracle Cloud : OCI
- 技術情報