Google App Engine上のアプリを段階的にリニューアルする


現状とやりたいこと

Google App Engine Pythonで作成された、古いアプリケーションがあります。
これがRESTとかも何も知らない頃に、独自に考えてAPIを作ったので、クライアント側などで無理が出てきました。(レスポンスがJSONじゃないのでパースし辛いなど)

この際にAPIを一新し、Webフロントエンド・iOS・Androidのそれぞれからのリクエストもそちらに切り替えたくなりました。
ただ、アプリ側には強制バージョンアップ機能などもなく、並行動作させる期間を設けたいと考えました。1
(数ヶ月ぐらい並行稼動してれば、それなりにアクティブなユーザはアプリを更新してくれるだろう、と割り切ります。)

Google App Engineと同一プロジェクト内のCloud Datastoreを利用しており、そこは引き続き利用したいと思います。

手順イメージ

Google App Engineのserviceを新規に作成することとしました。

  1. 既存のプロジェクト内に、新規サービスとして v2 を作成し、そこに既存と同等の機能を持つAPIを実装。
  2. 既存サービスとv2を並行稼動させ、 /v2 以下のリクエストについては、v2サービス側に流す。
  3. iOS・Androidのクライアントからは、v2を利用するように変更、リリースする。

この状態でのイメージ図

そのあと、

  1. v2上で新しいフロントエンドを作成。(APIリクエストもv2に向ける)
  2. すべてのリクエストがv2サービスに流れるように変更。(古いアプリからはアクセス不可になる)
  3. 既存サービスを停止する。

この状態でのイメージ図

具体的な要素技術

複数のサービスを共存させる

app.yamlservice を指定することで、別サービスとして並行稼動させることができます。

ドキュメント: https://cloud.google.com/appengine/docs/standard/python/config/appref?hl=ja

何も指定していないと、 default というサービスで起動されます。

サービスごとに全く別のコードベース・Runtimeを利用することもできます。
(今回も、既存はPythonですが、新規APIはGoで実装中です)

URLを振り分ける

iOS/Androidアプリからの利用を想定すると、ドメイン・パスの変更回数は減らしたいです。
既存サービスの有無に関わらず、同一ドメイン・パスでアクセスし続けられれば良さそうです。

そこで、新しいAPIは /v2 以下のパスに作成し、既存のドメインでも /v2 以下のリクエストはv2サービスに振り分けます。

そのため、まずは dispatch.yaml というファイルを新たに下記のように作成しました。

dispatch:
  - url: "*/v2/*"
    service: v2

次に、これをデプロイします。

gcloud app deploy dispatch.yaml

これにより、既存ドメインの /v2 以下にアクセスすると、v2サービスが実行されることになります。

ドキュメント: https://cloud.google.com/appengine/docs/standard/go/reference/dispatch-yaml?hl=ja


  1. 強制バージョンアップがあったとしても、開発側からのアプリ公開してから、全ユーザが新しいアプリを利用可能になるまでのラグがあり、それを開発側からはコントロールできないので、長時間のサービス停止が必要になってしまいます。