REST API構築の仕事を請け負ったので、docker-composeで、Nginx+Flask+MySQLの構成で構築しました。
その時のことをまとめておきます。
※本記事の内容は、導入にいたった経緯や技術選定時に考えたことについてです。実際の設定内容、ソースコードや設定値の記載はありません。
前提
REST API構築にあたり、EC2のみしか使えないという謎の制限がありました。
この制限のせいで、急にこの仕事の難易度が上がりました。API GWとLambdaでサクッと作れそうなAPIだったのですが・・・ Fargateは使用不可、RDSも使用NGという徹底ぶりです。
(まさか今時、APIの新規開発をEC2で作ることになるとは・・・)
どうやら、発注元の人がAWSのマネージドサービスの概念がわからない人らしく、サーバ上にシステムを構築するということしか理解できないとのことです。
そんな人がいまだにシステム構築の管理業務をすることがあるんですね。ビックリです。
私はその人とは直接関わることがないところに位置しているのですが、心底助かったと思いました😅
私と発注元の間に入っている人は、相当ストレスが溜まっていそうです。ドキュメントもExcelやパワーポイントのみで、チケット管理の概念も知らなさそうで、やりとりはメールベースのPPAPらしいです。
(か、かかわりたくない・・・💧)
技術選定
自由にやってOKだった
EC2という縛りはあるものの、それ以外の技術選定は好きにしていいとのこと。まあ、おそらく技術の話はできないので、丸投げって感じなんでしょう。
最終的には、以下の構成でやることにしました。
DBもとりあえずAPIと同じEC2でやることにします。
後で分離するかもしれませんが、どうせEC2を使わないと行けないなら、運用負荷や耐障害性もあまり変わらないと思うのですが、どうなんでしょう。
言語はPythonにした
私はGo言語の実務経験が、いまだにありません。なので今回はチャンスだと思って、Go言語でやろうと思いました。ただ、以下の理由で慣れ親しんでいるPythonで行くことにしました。
- 副業なのであまり時間をかけられない
(Go言語より他に優先して勉強したいことがある) - これからはメインの仕事がデータエンジニアになる。PythonとJavaが主要言語になり、Go言語は当分使うことがなさそう。
- 最近、Pythonをあまり書いていなかったので感覚が鈍ってきた
WebフレームワークはFlask
最近はサーバレス構成でAPIを作ることが多かったので、Webフレームワークを使うのはひさしぶりです。
最近のWebフレームワーク事情は疎かったのですが、少し前とあまり変わっていないようです。
Pythonだと、Django, Flask, FastAPIあたりが選択肢になりそうです。
今回はAPIのみで、UIはないのでDjangoは除外。FlaskとFastAPIは違いが良くわからなかったので、少しやったことあってWeb上のドキュメントも豊富そうなFlaskを選択しました。
あまり考えずにFlaskを選んだのですが、後日FastAPIについて少し調べてみたら、こっちのほうが良いかもと思いました。コードの書き方はFlaskとほぼ同じ、ナレッジも十分ありそうで、動作は速め、Open APIのドキュメントが自動で生成されるなど、いろいろ良いことがありそうです。
ただ、もうFlaskでやりますと言って構成レビューも終わった後だったので、Flaskで突っ走ることにしました。
Flask vs Flask-RESTful
Flaskには、REST APIに特化した拡張ライブラリFlask-RESTfulがあります。
Web上のFlaskでAPIを構築したという記事には、このFlask-RESTfulを使ったものと、従来のFlaskでやったものが散見しているので注意が必要です。
少し調べてみたのですが、Flask-RESTfulを使うメリットがあまり分かりませんでした。シンプルに書けるようになるみたいな記事もありましたが、コードの記述量はそれほど変わらない気がします。
Flask-RESTfulはエンドポイントをクラスで書いて、従来のものは関数で書くぐらいの違いしか、私には分かりませんでした。個人的には関数で書いてあった方が見やすいので、Flask-RESTfulは使わず、従来のFlaskの書き方でいくことにしました。
DBはMySQL
DBはMySQLにしました。
Docker on EC2でやるので、PostgresかMySQLしか考えませんでした。No SQLのDocker運用のナレッジが自分にはなかったので。
レコード数はそれなりに多そうなシステムですが、テーブル構成自体はシンプルで規模もそれほどではないので、今回はMySQLを選択しました。
ORMとマイグレーションツール
今回のAPIはinsertにかなりシビアなパフォーマンスが要求されそうなので、生SQLを使うことになるかもしれませんが、一応、ORMも導入しておくことにします。
PythonのORMは、SQLAlchemy一択かと思います。
FlaskにSQLAlchemyをサポートした拡張ライブラリ、Flask-SQLAlchemyがあるので、これを使うことにします。
またマイグレーション管理したいので、マイグレーションツールを導入することにします。これも独立したツールでなく、Flaskを拡張したFlask-Migrateがあるので、これを使うことにします。
Nginxを導入
Flaskは簡易サーバを包括しているので、Nginxを導入しなくてもAPIのレスポンスを返すことはできます。
しかし、起動時に使用は開発時のみにしてねと警告が出ます。というわけで、WebサーバとしてNginxを導入することにします。
NingxとFlaskの接続部、APIサーバとしてuWSGIを設定します。APIサーバは、uWSGIやGunicornあたりが主流です。
Gunicornの方が設定がシンプルですが、uWSGIのほうが早くweb上のドキュメントも豊富なのでuWSGIを使うことにしました。
まとめ
以上、Dockerで動作するREST APIを構築するための構成や技術選定についてでした。
Nginx+uWSGI+Flask+MySQLはよくある構成だと思います。Web上の記事も多いです。それでも、導入にあたり苦戦したこともあるので、実際の設定内容やソースを紹介しながらの続き記事も書きたいと思っています。
