漫然なリリースはやめよう


## Don't Push To Production On Friday

https://x.com/GithubProjects/status/1814208575985664083

## 漫然なリリースはやめよう

筆者がディレクターを務める[満洲開拓資料館](https://mus-manchuria.com)が開発しているデータ検索システム「[横断型情報検索管理システム One Cross-Search](https://mus-manchuria.com/ja/ocs)」が、先日（2025.05.01）アップデートされました。

https://mus-manchuria.com

2024年8月のリリース以降2度目のアップデートとなりましたが、過去一番に空気がピリッとした切り替えだったので、工夫した点などをまとめてみます。

## アーキテクチャと改修範囲

![スクリーンショット 2025-05-02 7.46.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2611822/cdca117a-b2d7-417d-ab12-2da0111bd223.png)

本システムはGoogle CloudのCloud Run ServiceでホスティングされたWebアプリケーションです。Web用/API用が稼働しており、それぞれ異なるURLでインターネットから接続することができます。

WebのホスティングにはCSRを採用しており、システム利用時には
① ブラウザからCloud Run（Web）へ、コンテンツを取得
② クライアント側でレンダリング、ユーザーの操作（検索項目入力、ボタン押下など）
③ ブラウザからCloud Run（API）へリクエスト送信
というフローが発生します。

**本件の改修の主たる目的はAPIの出力フォーマットの変更**であり、フォーマットの変更に伴いフロントエンドの実装変更が発生します。

すなわち、改修範囲は
1. APIの実装・出力フォーマット
2. フロントエンドにおける、APIレスポンスの表示に関わる部分

の2点です。

## APIの改修

**バージョン管理をせよ。**
この一言に尽きます。

APIが外部提供するクエリやレスポンスフォーマットなどの仕様は、機能の追加・削除等によって変更を余儀なくされる場合が往々にあります。
API提供者が仕様を変更するのは容易ですが、API利用者がその変更に対して必要な対応を講じられなければ、API利用者側で障害が発生します。

そのため、外部仕様に破壊的変更がある場合、そもそもAPIのエンドポイントを分けてしまうべきでしょう。
機能変更を加えたバージョンをリリースしつつ旧来のバージョンも利用可能な状態とし、API利用者にバージョン変更を通達して、順次移行してもらう流れです。

```js
const API_ENDPOINT_V1 = "https://api.example.com/v1/user/"
const API_ENDPOINT_V2 = "https://api.example.com/v2/user/"
```

WebAPIのバージョン管理については、O'Reillyの「Web API: The Good Parts」が参考になります。

https://www.oreilly.co.jp/books/9784873116860/

なお本件のAPI改修では、APIのエンドポイント・クエリパラメータは変更せず、出力フォーマットのみを変更しました。
新規フォーマットを追加するだけであれば、バージョンを変更するのではなく、フォーマットを指定するクエリパラーメタを追加する方法も選択肢の一つでした。

```js
// default format: ex.) application/json 
const url_former = 'https://api.example.com/v1/user/'

// specify format: ex.) application/xml
const url_latter = 'https://api.example.com/v1/user/?format=application/xml'
```

## フロントエンドの改修・切り替え

APIの仕様変更はバージョニングで対応できますが、フロントエンドのリリースは「旧を新で置き換える」ことしかできません。

本件では、レンダリングにCSRを利用していること、WebAPIがインターネットからアクセス可能であることを利用して、次のような切り替え計画を立てました。

:::note info
本番環境をミラーリングしたステージング環境が準備できれば、以下の方法は不要かもしれません。
:::

① 開発環境で、新API（v1,v2を提供）と旧フロントエンド（API v1を利用）を起動し、動作の正常性を確認する。![スクリーンショット 2025-05-02 9.26.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2611822/b601ab5d-17ee-406d-801b-77f9df666682.png)


② 新APIをリリースする。本番環境で①が再現される。
![スクリーンショット 2025-05-02 9.26.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2611822/5571b609-17ed-4159-88ec-21f839db1c1a.png)

③ 開発環境で新フロントエンド（API v2を利用）を起動、本番環境の新APIに接続し、動作の正常性を確認する。
![スクリーンショット 2025-05-02 9.26.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2611822/886f5612-ceb3-4850-8f0a-7a600f03bad4.png)

④ 新フロントエンドをリリースする。システム切り替え完了。
![スクリーンショット 2025-05-02 9.26.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2611822/33c14cd1-53a3-4ab1-b13d-4c3f39331b36.png)

APIとWebの正常性確認・切り替えを順次行うことで、フロントエンドとAPIの連携に問題があった場合でも、開発環境でそれらの問題を発見し、本番環境に影響が出ないようにすることができます。

:::note warn
Webのソースコードを本番環境へデプロイする際に生じる固有の問題（ex. クラウド上での環境変数の変化など）については、この方法では捕捉できない場合があります。
:::

## おわりに
データ検索システム「[横断型情報検索管理システム One Cross-Search](https://mus-manchuria.com/ja/ocs)」のシステム切り替えに際して、注意した点・切り替えで工夫した点をご紹介しました。

Google CloudのPaaSコンピューティング基盤（Cloud Runなど）であればバージョニングを使った切り戻しも可能ですが、できる限り本番環境への影響が少なくなるような実装・オペレーションを採用しました。どこかでみなさんの参考になれば幸いです。

今回取り上げた「[横断型情報検索管理システム One Cross-Search](https://mus-manchuria.com/ja/ocs)」で利用しているNoSQLデータベース（RDF）やクエリ言語（SPARQL）については、別の機会にご紹介できればと思います。

ここまで読んでいただきありがとうございました！

https://x.com/GithubProjects/status/1814208575985664083