5分で作れる!FastAPI 入門編

クロスマート バックエンドエンジニアの武(タケ)(@pouhiroshi)です。
社内ではおそらく最高齢なため「たけじい」と呼ばれております。(けど入社して半年なので気持ちは若いです♪)これからよろしくお願いいたします。


前回は 小久保さんの「テストコード好きがテストを布教し続けた結果プロダクトや個人がどう変わったか」についての記事でした。
わたしも小久保さんに見習ってテストを頑張って書くようにしています!まだ、見ていない方はぜひこちらの記事もご覧ください。
xmart-techblog.hatenablog.com


さて、弊社のクロスオーダー 飲食店と卸をつなぐ受発注システムのバックエンドは、サービスイン当初からPythonフレームワークDjango+DjangoRestFramework(DRF)が採用されております。

今回、新しいサービス開発プロジェクトが立ち上がることになり、メインデベロッパーとして言語やフレームワークを選定したのですが、最近話題にあがっていて評価も高そうなFastAPIを使うこととしました。
fastapi.tiangolo.com


Pythonフレームワークgithubスター数はDjango, Flaskに次ぐ第3位!初版リリース2018年にして、上位を追い越しそうな勢いです!

選定した理由はいくつかあるのですが、
ポジティブな理由としては、

  • わかりやすい・かきやすい・自由がある
  • 使っている人が多くドキュメントや参考となる記事が多い
  • レスポンス速度が速い(らしい)
  • Javaで慣れ親しんだSwaggerが自動で生成されるらしいぜ!!!

ネガティブめな理由としては

  • 既存利用のDjango+DjangoRestFramework(DRF)が(私は)わかりにくい・・・!!

というものがありました。

特にDjango+DjangoRestFramework(DRF)がわかりにくいというのは、私がもともとJavaエンジニアでPythonDjangoをほぼ初めて使ったという理由も多分にあるとは思います。調べてみると私と同様「DRFはわかりにくい」と挫折(とまではいきませんが)した人は多いようです。

そんな中発見したのが、FastAPIです。
理由にも挙げた通り、わかりやすくシンプルな形で開発を行うことができます。
コンポーネント間のつながりも直感的でJavaでいうSpringBootと同じような感覚で開発を進めることができます。
さらにREST APIを開発する上でとても便利なSwaggerも自動生成されます。

今回は、「5分で作れる!FastAPI」と題して、FastAPIにおける開発を入門編としてご紹介したいと思います。
なお、開発環境はPyCharmを使っていますが、VSCodeなどでももちろん開発を行うことができます。ぜひ軽率にチャレンジしてみてください!

入門編目次

プロジェクト作成

PyCharmのプロジェクト作成で、作成するディレクトリを選んでFastAPIを選択します。

FastAPIとuvicorn(アプリケーションサーバ)がインストールされます。*1

すると、main.pyが作成されていると思います。


FastAPI Webアプリケーションの起動

いったん、右上のfastApiProject1(プロジェクト名)が出ている状態で再生ボタンを押しましょう。
アプリケーションが起動できます。

コンソールに Application startup complete.
と出たら起動成功です。
コンソールに出ている http://127.0.0.1:8000 をブラウザで表示してみましょう。

ブラウザに async def root(): に書かれている{"message": "Hello World"}
が表示されていますね。

何もしてないのにAPIができあがってしまいました!

アプリケーションは実行タブで Ctrl+Cで終了することができますし、実行ボタンの右のほうにある停止ボタンでも停止することができます。

ブレークポイントによるデバッグ実行

また、ブレークポイントをつけて、デバッグを行うこともできます。アプリケーションを停止したら、再生ボタンのよこにあるデバッグボタンで同じように起動してみましょう。

同じく、http://127.0.0.1:8000 をブラウザで表示してみましょう。
ブレークポイントで 実行が止まりましたね!

こちらで実行中の変数などをみてステップ実行することができるようになります。
これがなくては開発が捗りませんね!

Router(Controller) の定義

main.pyにはAPIのパスとhttp methodを定義する @app.get("/") という表記がありますね。

@app.get("/") は ルートパスをにGETアクセスした際の処理がかかれています。

@app.get("/hello/{name}") の{name}部分はパス変数と呼ばれており、対応するアドレスは http://127.0.0.1:8000/hello/{name変数に入れる値}となります。

main.py

from fastapi import FastAPI

app = FastAPI()


@app.get("/")
async def root():
    return {"message": "Hello World"}


@app.get("/hello/{name}")
async def say_hello(name: str):
    return {"message": f"Hello {name}"}

ブラウザで http://127.0.0.1:8000/hello/FastAPI にアクセスしてみましょう。

ブラウザに {"message":"Hello FastAPI"} と表示されましたね!
URLのパスであたえたFastAPIという文字列がnameという変数に入り、say_hello(name: str)の引数nameで受け取れたことが確認できたと思います。

デバッグでも確認してみましょう。

ソースコード上やマウスオーバーで変数が表示されますし、下のデバッグコンソールにも値が表示されていますね。

デバッグが捗りそうです。

Swagger (APIドキュメント) 自動生成

FastAPIはAPI開発に特化しており、エンドポイントを作成すると同時にSwaggerというAPIドキュメントが生成されます。
アプリケーションを起動すると見れるようになります。
アプリケーションを起動し、http://127.0.0.1:8000/docs へアクセスしてみましょう。

このように@app.get で定義されている2つのエンドポイントが出ていますね。
アコーディオンを開くと詳細を確認することができます。

このようにパラメータやレスポンスの仕様について確認することができます。

SwaggerによるAPI実行(Try it out)

右上についているTry it out ボタンを押すと、実際にこのAPIにパラメータなどを与えて実行することができます。

今回は、わたしの社内でのニックネーム「たけじい」を入力して、Executeを押してみます。

すると、このようにCurlでリクエストした場合とURLリクエストした場合の表記がでてきて、
さらにhttp status codeとResonse body が表示されます。
正しくjson形式で
{
"message": "Hello たけじい"
}
と返ってきているようですね!

まとめ

いかがでしたでしょうか。
FastAPIをつかってAPIサーバーサイドを、素早く、かつシンプルな形で実装することができることを実感いただけたかと思います。

説明しきれていない部分もたくさんありますので、今後もFastAPIの情報をお伝えしていこうと思いますのでご期待ください。

FastAPIを使いたいとエンジニアチームの技術定例で提案したとき、「使いやすそう」「おもしろそうじゃんやってみなよ」というメンバーからの反応があったように、弊社には新しいことにチャレンジすることへの前向きな雰囲気があります。

開発メンバーをバックエンド、フロントエンド、共に絶賛募集中です!

ぜひ新しいことにチャレンジできる環境の中で一緒に楽しくお仕事しましょう!

www.wantedly.com

*1:Pycharmを使わない場合はプロジェクトディレクトリ作って、その中で pip install fastapi pip install uvicorn でインストールしてもOKです