見出し画像

Cloud Functions, Firebase Functions, Google App Engineの特性

はじめに

@yutakikuchi_です。
Google Cloudの環境でHttp Requestを受けるAPIを開発したいのですが、選択肢として、例えば下記のような方法があります。

1. GCPのCloud Functionsを利用する
https://cloud.google.com/functions
2. Firebase Functionsを利用する
https://firebase.google.com/docs/functions
3. Google App Engineを利用する
https://cloud.google.com/appengine

それぞれの特性の違い

少しずつ特性の違いがあるので簡単に記載すると、
1, 2のCloud Functions/Firebase Functionsは従量課金制のFunctions as a Service(FaaS)。EventのTriggerとして、HTTPだけではなく、FirebaseやCloud Pub/Sub, Cloud StorageへのEventにも対応しています。対して、3のGoogle App EngineはWebアプリケーションに特化したサービスなので、基本はHTTPだけの対応になります。

Cloud FunctionsとFirebase Functionsの違いとしてはFirebase Functionsの方がアプリ開発向けに機能を特化したり制限したものです。Firebase Functionsにのみある具体的な機能として
・Cookieを扱える
・API Endpoint(URI)のRouting Pathを柔軟に作ることができる

ただし、Cloud FunctionsはGoやPython,JavaScriptでも記載が可能ですが、Firebase FunctionsはJavaScript,TypeScriptしかサポートしていません。Firebase FunctionsでPythonを書きたいと言っても、2022.01.08の時点ではできない状況にあります(涙)。

よって、注意が必要なこととして、2. Firebase FunctionsだけではPythonでHTTP Requestを受け付けることができないため、Pythonなどを使いたい場合は、Firebase HostingとCloud Functionsと組み合わせて使う必要があります。

通常、Cloud Functionsに関数を登録すると下記のようなDomainとURLになります。
https://<REGION>-<FUNCTIONS_PROJECT_ID>.cloudfunctions.net/<FUNCTIONS_NAME>

上のURLのブログを参考にすると、1のCloud FunctionsにPythonで書かれた関数本体を載せて、Firebase Hostingのrewritesの設定を使うことで、API EndpointのURIを多階層にするなどの設定が可能であり、Cloud Functionsの関数を呼び出すことができます。その他の方法として、Endpointを柔軟に設定する方法として、ESPv2を利用するなどもあるかと思います。


繰り返しになりますが、1. Cloud Functionsへの関数登録だけでは関数呼び出しのEndpointがシンプルなものに限定され、多階層にするなど柔軟に組むことが出来ません。

Cloud Functionsで書かれたコードをGoogle App Engineにも展開

Cloud Functions向けに書いたコードをGoogle App Engineに流用することも可能です。Cloud Functions向けに書いたコードのディレクトリに対して、下記の追加ファイルを設定するだけです。 ※RuntimeとしてPython3.7、Flask利用、Local環境での実行を想定したものになります。

Google App Engine用に必要な追加ファイルとしてapp.yamlとmain.pyがあります。
1. app.yaml

runtime: python37

handlers:
- url: /.*
 secure: always
 redirect_http_response_code: 301
 script: auto

Google App Engineのruntimeがpython3以上のものは、handlersのurlとscriptでうまく関数のEndpointがコントロールできないので(このあたり、原因不明)、main.pyに@app.routeを記載して、Cloud Functions向けに書かれた別ファイルの関数を呼び出すようにします。

2. main.py

from flask import Flask, request
from hello import *

app = Flask(__name__)

@app.route("/")
def route_hello():
 return call_hello(request)

Cloud Functions向けに用意したhello.py というファイルにcall_hello関数を作っていた場合、Google App Engineから呼び出すためにmain.py内で関数をimportして、@app.routeでURIの指定と、main.py内での関数の呼び出しを切り分けるだけです。

結論として

HTTPに閉じずに様々なEventを元にした処理を行いたいのであれば、関数やコードの登録先としてCloud Functionsを使いましょう。(Firebase Functionsと比べて登録できるプログラミング言語的な縛りもないため。) 上で書いたように、Cloud Functionsで書いたコードを後からGoogle App Engineでも利用するといったことも可能なので、第一選択としてはCloud Functionsで考えると良いと思います。

いいなと思ったら応援しよう!