このブログをリリースした当時から予定していましたが、やっとこさNode.js(Express)で書いていたAPIサーバをPython(Flask)に書き換えました。

なぜPythonに切り替えたのか

Pythonにしたかったから、というわけではなくて、単純にサーバサイドでJavaScriptを使いたくなかったというのが正直なところです。
確かにNode.jsで(ちゃんと)書いておけばC10K問題に対応出来るなどメリットはあるのでしょうが、このブログでは全く必要な要素でありませんでした。
また、Nuxt.jsをExpressで動かして、APIサーバもSSRサーバも同じNode.jsプロセスで提供するようにしてしまっていたので、それもなんだか気持ち悪いなと思っていました。
あとブログですので管理画面では画像をアップロードする機能があるのですが、どうもNode.jsではライブラリを使うのが一般的なようで、multerというものを利用していましたが、このような一般的なWebアプリケーションで利用される機能が標準では無い、もしくは煩わしいコードを書く必要がある点も可能な限りサーバサイドではJavaScriptを書きたくない理由の一つです。

当然これらの感想は、私のJavaScript/Node.jsに関する理解度の低さに起因する部分が大きいと思います。ただ、ちょっと時間配分や自分の仕事/プライベートの今後の方向性を考えると、JavaScriptはフロントエンドに限って勉強したほうが良いな、という結論に達しました。

そこで、今年はPythonを勉強するぞ!と決めてちょっとずつ進めていたので、じゃあPythonで書きなおすか、という流れです。
なお、私の大好物のApache GroovyGrailsを使えば10分もあれば充分に書きなおす事も出来ましたが、それだと勉強にならないので見送りました。

やったこと

フレームワークの選定

Pythonで書き直す、ということは決まったので、利用するフレームワークは勉強も進めていたのでBottleにしよう、と思っていたのですが、どうもルーティング周りに難有り、と判断したので、メジャーなFlaskを利用することに決めました。
FlaskにRESTful APIサーバを構築するのに便利な機能を被せたFlask-RESTful という物があるようです。
が、可能な限りシンプルな構成で行きたかったのと勉強も兼ねて、Flask本体でRESTful APIサーバを構築することに決めました。

Flaskの学習

今回の学習と実装で得られた知識は、別途それぞれ独立した記事として投稿したいと思います。
実際に今回学習、実装する際に調べた点は大雑把には以下のような内容です。

  • CORSの設定
  • JWTトークンの取り扱い
  • MongoDBの利用方法
  • 開発/テスト/本番での環境の切り替え方法(MongoDBの情報とか)
  • FlaskのBlueprintのユニットテストの実行方法
  • デプロイ方法

上記以外にも細かなPythonの動作(パッケージとモジュールとか)でも色々ハマりました。
やはりこういうハマりを経験することが大事なので、今回実際にPythonを利用してみて大正解だったと思っています。

Nuxt.jsの調整

基本的にAPIサーバを入れ替えるだけなので特に大きく変える必要はなかったのですが、今まで同じポートでWeb(Nuxt.js)とAPI(Express)を提供していたので問題ありませんでしたが、今回PythonでAPIを書き換え、別々のポート(本番環境ではドメインが違う)で提供するようになりました。
そこで、当然Nuxt.jsで開発/本番時のAPIサーバのドメインを切り替える必要が出てきました。
以下はそのために必要な記述を追加した最終的なpackage.jsonの一部です。

  • package.json(抜粋)
  "scripts": {
    "dev": "API_SERVER=http://localhost:5000 APP_SERVER=http://localhost:3000 nuxt",
    "build": "nuxt build",
    "start": "HOST=0.0.0.0 nuxt start",
    "generate": "nuxt generate",
    "lint": "eslint --ext .js,.vue --ignore-path .gitignore .",
    "precommit": "npm run lint"
  },

通常のNode.jsで動くアプリケーションであれば、上記のdevのようにコマンド実行前に指定した環境変数がNode.js上でprocess.env.API_SERVERという形で取得できるようです。
しかし、開発環境であれば問題なかったのですが、本番サーバ(startの部分)で同様に値を記述していても、本番環境だと何故か取得できずにundefinedになってしまいました。

そこで、nuxt.config.jsに以下のような内容を追記しました。

  env: {
    // if Nuxt.js runs as "production", process.env is not set with package.json.
    appServer: process.env.APP_SERVER || 'https://doitu.info',
  }

これで、Vueファイルの<script>の中であればprocess.env.appServerという形でちゃんと参照できるようになりました。
Nuxt.jsで独自の環境変数を扱いたい場合は、必ずこのnuxt.config.jsで指定して、それを利用する必要があるようです。

なお、このprocess.env.キー名が使えるのはあくまでVueファイルの<script>内です。
もしテンプレート内でprocess.env.キー名を参照したい場合は、computedの中でこの環境変数を参照するメソッドを作成して、それを利用する必要が有りました。

まとめ

見た目が変わったわけでもなく、大きな機能が追加されたわけではないですが、こうやって実際に色々な言語やツールを使ってみて問題点や疑問点を見つけていくことでやっと見えてくるものがあるんだな、と改めて思いました。