ResponderとFastAPIを実際に使って比較してみた
IT技術
ResponderとFastAPIを比較したい!
Webアプリケーションといえば、PHPの「CakePHP」、Pythonの「Django」、Rubyの「Rails」などが有名ですね。
そんな中、最近注目されてきているWebフレームワークがあります。
本ブログでも、使い方の例を紹介している『 Responder 』と『 FastAPI 』。
今回は、この2つのフレームワークを実際に使ってみて、気づいたことをまとめて比較してみようと思います。
少し主観が入る部分がありますが、ご了承ください。
ResponderとFastAPIの連載記事はこちら
ResponderとFastAPIの共通部分について
まずは、今回比較する2つのフレームワークについて、簡単にご紹介したいと思います。
実は、この2つのフレームワークは共通している部分がいくつかあります。
Starletteベース
Responder と FastAPI は、Starlette (スターレット: フランス語で”小さな星”) がバックで動作しています。
つまり、どちらのフレームワークも Starlette をラップしたフレームワークということです。
Starlette は、あまり日本では流行っていませんが、このフレームワークは様々な機能が詰め込まれており、拡張性に長けています。
Responder と FastAPI を使う場合は、Starlette の機能も使おうと思えば使用可能です。
また、Starlette におけるサーバーの起動は、Uvicorn と呼ばれるフレームワークを扱っているので、これは Responder と FastAPI においても同様となっています。
ただし、注意点として、Responder と FastAPIでは扱うStarletteのバージョンが異なります。
【Starlette 公式サイト】
https://www.starlette.io/
Jinja2テンプレートエンジン
これも Starlette が Jinja2 をサポートしているので当たり前なのですが、HTML生成にはResponder と FastAPI においても、Jinja2テンプレートエンジンが使用できます。
ただし、詳細は後述しますが、Responder の方が扱いやすくラップされている一方で、FastAPI では、直接 Starlette を経由して扱うことになります。
非同期処理に強い
Responder も FastAPI も、非同期処理を簡単に実装することができます。
Responder
特に、Responder では、@api.background.task デコレータを関数につけるだけでOKなのは便利ですね。
FastAPI
FastAPI では、from fastapi import BackgroundTasks したのち、引数で以下のように指定してあげることで、バックグラウンドタスクとして実行が可能です。
1def index(request: Request, bg_task: BackgroundTasks):
2 # バックグラウンドタスクとして追加
3 bg_task.add_task(Something)
ただし、非同期処理と言っていますが、バックグラウンドで実行されたタスクから、終了のレスポンスは直接受け取ることができないので注意が必要です。
MVCアプリケーションを作成する場合
まずはビューを持つ、一般的なWebアプリケーション(MVC: Model View Controller)について見ていきましょう。
MVCに強いResponder
Responderは、対ユーザーのMVCアプリケーションを作成するのに特化しています。
Responderでは基本的に、インポートするのはimport responder のみで済み、比較的コードが乱雑になることなくアプリケーションを構築できます。
先ほどの Jinja テンプレートについても、responder.API.jinja_env が Jinja2 の環境変数になっており、設定も容易です。
フィルタ
例えば、フィルタは以下のようのに追加できます。
1# ResponderのAPIインスタンス
2api = responder.API()
3
4
5# staticをjinja2で解決するためにstaticフィルタを定義
6def static_filter(path):
7 return '/static/' + path
8
9
10# staticをフィルタに追加
11api.jinja_env.filters['static'] = static_filter
テンプレートをビューに渡す
テンプレートをビューに渡す場合も、
1resp.content = api.template("index.html",
2 arg1=arg1,
3 arg2=arg2,
4 )
のように、ResponderのAPIクラスにJinjaテンプレートが扱えるメソッドが用意されています。
ここで注目すべきなのは、Starletteが見えていないことです。
あくまで、プログラミングする側は「Repsponder」を扱っているだけなのです。
サーバーの起動
サーバーの起動も、裏で Responder がよろしく Uvicorn を起動してくれているので、
1api.run()
だけでOKです。
MVCに弱いFastAPI
一方で、FastAPI はビューを持つアプリケーションには対応していません。
もし、先ほどの Responder と同じようなことをやろうとすると、
1from starlette.templating import Jinja2Templates
2
3# テンプレート関連の設定 (jinja2)
4templates = Jinja2Templates(directory="templates")
5jinja_env = templates.env # Jinja2.Environment : filterやglobalの設定用
6
7
8def index(request: Request):
9 # Jinja2のよるHTML生成
10 return templates.TemplateResponse('index.html',
11 {'request': request})
のように、Starlette の機能を直接使わなければなりません。
サーバーの起動
また、サーバーの起動は、FastAPI の場合、Uvicorn を自分でインポートしなければなりません。
1import uvicorn
2
3# コンソールで [$ uvicorn run:app --reload]でも可
4uvicorn.run(app=app)
WebAPIを作成する場合
続いて、「WebAPI」と呼ばれる、対プログラムのアプリケーションを作成する場合について比較していきましょう。
WebAPI作成にもやや強いResponder
Responder は、もちろんWebAPIを作成するのにも向いています。
JSON/YMAL をレスポンスする場合
JSON/YMAL をレスポンスする場合は、
1resp.json = {'Hello': 'world'}
2resp.media = {'Responder': 'Python'}
のように記述できます。
レスポンスのステータスコード
レスポンスのステータスコードも、
1resp.status_code = api.status_codes.HTTP_500
のように設定可能です。
WebAPIのドキュメント
WebAPI のドキュメントも
1import responder
2
3api = responder.API(
4 title='Polls Application with Responder',
5 version='1.0',
6 openapi='3.0.2',
7 docs_route='/docs',
8 description='hogehoge',
9 contact={
10 'name': 'RightCode Inc. Support',
11 'url': 'https://rightcode.co.jp/contact',
12 'email': '****@abcdefg.com'
13 }
14)
で自動である程度作成されます。
各URLに対応したドキュメントは、自動では生成してくれず、各メソッドに直接 Swagger を記述する必要があります。
WebAPI作成に強いFastAPI
一方、FastAPIはその名の通り、WebAPI を作成するのに特化しています。
JSON/YMALをレスポンスする場合
JSON/YMAL をレスポンスする場合は、辞書型変数を返すだけでOKです。
例えば、
1def hoge(request: Request):
2 # returnでJSONで返す
3 return {
4 'id': '1',
5 'username': 'John Doe',
6 'Age': 20,
7 }
のような感じです。
認証やPOSTデータの受け取り
また、認証やPOSTデータの受け取りは、FastAPI でサポートされている、以下のメソッドを使用することができます。
1from fastapi import (FastAPI,
2 Depends, # 認証系
3 Form) # フォームデータ受け取り
4from fastapi.security import (HTTPBasic, # Basic認証
5 HTTPBasicCredentials)
Basic認証を行いたいURL では、引数を以下のように指定するだけです。
1def get(credentials: HTTPBasicCredentials = Depends(security)):
2 # Basic認証で受け取った情報
3 username = credentials.username
4 password = credentials.password
フォームでデータ受け取る場合
フォームでデータ受け取る場合は、
1async def insert(request: Request,
2 username: str = Form(...), password: str = Form(...)):
のように引数を指定してあげることで可能になります。
自動生成
また、これらの記法によってコードを記述することによって、各URL処理の Swaggerドキュメントを自動で全て生成されます。
ドキュメントは「 /docs 」
静的なReDocは「 /redoc 」
で確認することができます。
これが、FastAPIの大きな強みと言えます。
まとめ
まとめると、以下のようになります。
- ビューを持つアプリケーションやAPIを作るのなら Responder
- 高速なレスポンスを期待するAPIに特化したアプリケーションなら FastAPI
今回比べた2つのフレームワークは似ていますが、「何をターゲットとしているか」は異なります。
正直、裏で動いている Starlette の守備範囲が広いので、Responder にできることは FastAPI にもできますし、逆も然りです。
しかし、重要なのは、何を作ろうとしているのかです。
他のブログでも、Responder と FastAPI についての記事をいくつか掲載しているので、どのようなモノが作れるのか、是非読んでみてくださいね!
こちらの記事もオススメ!
2020.07.28機械学習 特集知識編人工知能・機械学習でよく使われるワード徹底まとめ!機械学習の元祖「パーセプトロン」とは?【人工知能】ニューラルネ...
2020.07.17ライトコード的「やってみた!」シリーズ「やってみた!」を集めました!(株)ライトコードが今まで作ってきた「やってみた!」記事を集めてみました!※作成日が新し...
ResponderとFastAPIの連載記事はこちら
ライトコードでは、エンジニアを積極採用中!
ライトコードでは、エンジニアを積極採用しています!社長と一杯しながらお話しする機会もご用意しております。そのほかカジュアル面談等もございますので、くわしくは採用情報をご確認ください。
採用情報へ
「好きを仕事にするエンジニア集団」の(株)ライトコードです! ライトコードは、福岡、東京、大阪、名古屋の4拠点で事業展開するIT企業です。 現在は、国内を代表する大手IT企業を取引先にもち、ITシステムの受託事業が中心。 いずれも直取引で、月間PV数1億を超えるWebサービスのシステム開発・運営、インフラの構築・運用に携わっています。 システム開発依頼・お見積もり大歓迎! また、現在「WEBエンジニア」「モバイルエンジニア」「営業」「WEBデザイナー」を積極採用中です! インターンや新卒採用も行っております。 以下よりご応募をお待ちしております! https://rightcode.co.jp/recruit