やわらかテック

興味のあること。業務を通して得られた発見。個人的に試してみたことをアウトプットしています🍵

ステータスを返すだけのAPIをほぼ無料・爆速でCloud Runに作成する

ただスタータスを返すだけのAPIが別のホストに必要になったので作ってみました。
多くのケースではPrismでモックサーバーを立てれば十分ですが、ヘッダーにPreferの指定ができない上に固定のステータスが返ってくれば良いだけだったので自分で作ることにしました。

stoplight.io

今回はGoogleCloudPlatform(GCP)のCloud Runにgoで作った簡易なサーバーをデプロイするという選択をしました。Cloud Runは従量課金制ですが、呼び出す回数が少ないので無料枠に収まる想定です。また実装にgoを選定したのは、この手のミニマムのサーバーを作るのが楽だからです。

ソースコードはgithubにて公開しています。

github.com

goのコードを触ることなくAPIをCloud Runに作成することが出来るようになっているので、サクッとCloud RunにAPIを作成したい方は以降、使い方をご覧ください。

APIの作成

フォルダ内のserver_setting.jsonを編集すればAPIのエンドポイントとレスポンス時のステータスが指定できます。試しに/api/v1/echoから204ステータスが返ってきて欲しい場合は、以下のように指定してください。

{
  "port": 8080,
  "endpoints": [
    {
      "path": "/api/v1/echo",
      "status": 204
    }
  ]
}

追加で/api/v1/pingから200ステータスを返したいのであれば、同じように配列に要素を追加します。

{
  "port": 8080,
  "endpoints": [
    {
      "path": "/api/v1/echo",
      "status": 204
    },
    {
      "path": "/api/v1/ping",
      "status": 200
    }
  ]
}

以降、APIを増やしたいのであれば同様の手順で追加していきます。
もしレスポンスボディも返して欲しいという声があれば対応を検討しますが、冒頭でも書いたようにそういったケースではPrismを使った方が良いでしょう。

ローカル環境でのテスト

goがインストールされてれば、以下をターミナルで実行することで8080ポートでサーバーが立ち上がります。
もしポートを変更したければ、jsonファイルのportの値を指定のものに変更してください。

$ go run main.go
2023/06/27 22:15:59 listening server on port 8080

サーバーを立ち上げている状態でcurlなどを使ってAPIを呼び出します。
curlの実行結果からステータスだけを取得するのが少し面倒なので、フォルダ内にclient.shというシェルスクリプトを用意しました。このシェルスクリプトに実行時引数を以下のように指定することで、API呼び出しの結果を確認することが可能です。

$ bash client.sh "localhost:8080/api/v1/ping"
response status(localhost:8080/api/v1/ping): 200

$ bash client.sh "localhost:8080/api/v1/echo"
response status(localhost:8080/api/v1/echo): 204

Cloud Runへのdeploy

最近知ったのですが、gcloud run deployというコマンドを叩くだけでCloud Runへデプロイが出来ます。
フラグ値を複数指定しなくても、対話形式で値の指定がされていくため、非常に便利です。デプロイをより簡単に行うために同じようにフォルダ内にはdeploy.shというシェルスクリプトを用意しました。

ここでは以下3つが達成されていることを前提としています。

  • GCPにプロジェクトが作成されていること
  • gcloud CLIがインストールされていること
  • gcloud configにプロジェクトが登録されていること

gcloud CLI の概要  |  Google Cloud CLI のドキュメント

deploy.shを実行すると、まず現在、登録されているプロジェクトが表示されます。

$ bash exec_deploy.sh 
project = hoge-project

Your active configuration is: [foo]

その後、デプロイしてもOK?という確認が入ります。問題なければyを。中止したければnを入力します。
yを選択するとgcloud run deployが実行され対話形式で値の設定が始まります。

$ bash deploy.sh 
:
Is it okay to deploy to Cloud Run with these settings?(y/n)y
:
Service name (mock-server):  
Please specify a region:
 [1] asia-east1
 [2] asia-east2
 :
Allow unauthenticated invocations to [mock-server] (y/N)?  y

Building using Buildpacks and deploying container to Cloud Run service [mock-server] in project [hoge-project] region [asia-east1]
✓ Building and deploying new service... Done.                                                                                                
  :
Done.                                                                                                                                        

無事にCloud Runに新規サービスが作成されました。

regionはそこそこ近めのasia-east1で、認証(Allow unauthenticated)はyesにしておくことをオススメします。

コードについて

最後に補足ですが、コードについて簡単に説明をしておきます。
まずはjsonから読み込んだ値をgoの構造体に変換します。その後、endpointsに指定されていたAPIの一覧をfor文を使って1つ1つ取り出してhttp.HandleFuncを利用して順番にAPIの登録をしていきます。ここでは無名関数を使うことで動的にAPIを登録できるようにしました。

for _, ep := range s.Endpoints {
    http.HandleFunc(ep.Path, func(w http.ResponseWriter, r *http.Request) {
        if ep.Status >= 100 && ep.Status < 600 {
            w.WriteHeader(ep.Status)
        } else {
            log.Fatalf("The specified %d is not a valid status.", ep.Status)
            os.Exit(1)
        }
    })
}

少しでも「ええな〜」と思ったらイイネ!・シェア!・はてなブックマークを頂けると励みになります。