Golang PR

Vercel Serverless Function with Golangを試してみた+Github Actionsでデプロイ!

VercelServerlessFunctionwithGolangAndGithubActions
記事内に商品プロモーションを含む場合があります

今、開発しているアプリのバックエンドを
Golang+Serverlessで作りたいなと思い立ちました。
AWS Lambdaかなと最初は考えたのですが、
フロントエンドで使っているVercelがServerless Functionも
提供しているということで、Golangもいけそうだったので試してみました!
ついでに毎回手動でデプロイが面倒なので、
Github ActionsでCDを作ってみましたので、そのメモです。
同じようなことしている方の参考になれば幸いです。

Vercel Serverless Function with Golang

Sampleを作成・デプロイ

本家のサイトを参考にトライ。
まずはSampleアプリを作成・実行してみます。
コードを私のリポジトリにアップしたのでご参考まで。
※情報が少ないので試行錯誤しました

  1. GithubのCodespacesを立ち上げます
    ※Docker環境とか作るのが面倒だったので
     npmとgoが使えるなら他の環境でもOKかと
  2. Vercel CLIのインストール
    npm install -g vercel
  3. バージョン確認(スキップでもOK)
    go version go1.21.5 linux/amd64
    node v20.10.0
    npm 10.2.3
    Vercel CLI 33.0.1
  4. vercel login
    ※何でもいいですが今回はメールアドレスでログイン
  5. sampleプロジェクト作成
    mkdir sample
    cd sample
    go mod init sample
  6. プロジェクトのフォルダを作ります。
    mkdir api
    touch api/index.go
  7. index.goを編集します。
  8. ビルド設定ファイルを作ります。
    touch vercel.json
  9. デプロイします。色々質問されますがデフォルトを選択(Enter)
    vercel –prod
    ※事前に動作確認したい場合はvercel devで実行できます。
     GithubがURLを払い出してくれて、
     自分のPCからアクセスできるので便利!!
  10. 動作確認して終了!
package handler

import (
	"fmt"
	"net/http"
)

func Handler(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintf(w, "<h1>Hello from Go!</h1>")
}
{
    "build": {
      "env": {
        "GO_BUILD_FLAGS": "-ldflags '-s -w'"
      }
    }
}

動作確認

VercelSample

別のAPIを作成

これだけではアレなので
もう一個くらいAPIを追加してみました。
最終系は以下です。リポジトリも今はこの状態
api/v1/hello/index.goとフォルダとファイルを作ってみました。

package hello

import (
	"encoding/json"
	"log"
	"net/http"
)

type Hello struct {
	ID      string `json:"id"`
	Message string `json:"message"`
}

func Handler(w http.ResponseWriter, r *http.Request) {
	switch r.Method {
	case http.MethodGet:
		h := Hello{
			ID:      "1",
			Message: "Hello World!",
		}
		w.Header().Set("Content-Type", "application/json; charset=utf-8")
		w.WriteHeader(http.StatusOK)
		if err := json.NewEncoder(w).Encode(h); err != nil {
			log.Println(err)
		}
	default:
		w.WriteHeader(http.StatusMethodNotAllowed)
	}
}

あとはこのAPIへのルーテイングを作成します。
vercel.jsonを編集して、以下のような感じにします。

{
    "build": {
      "env": {
        "GO_BUILD_FLAGS": "-ldflags '-s -w'"
      }
    },
    "routes": [
        { "src": "/api/v1/hello", "dest": "/api/v1/hello" }
    ]
}

動作確認2!Postmanでもやってみました。
ちゃんとGet以外ははじかれますね。

API200OK
API405Error

Github ActionsでCD

Sample作ってる時は、
vercel –prodで手動デプロイしていましたが、
コミットしたら自動でデプロイさせたかったので
サクッと作ってみました。Nodeのテンプレをベースに作成しています。

name: Vercel Serverless Function Sample CD

on:
  push:
    branches: [ "main" ]
  pull_request:
    branches: [ "main" ]

jobs:
  deploy:

    runs-on: ubuntu-latest

    strategy:
      matrix:
        node-version: [20.10.x]
        
    steps:
    - uses: actions/checkout@v3
    - name: Use Node.js ${{ matrix.node-version }}
      uses: actions/setup-node@v3
      with:
        node-version: ${{ matrix.node-version }}
        cache: 'npm'
    - run: npm install -g vercel
    - run: vercel --version
    - name: Deploy to Vercel
  working-directory: sample
      run: vercel --yes --prod --token=${{ secrets.VERCEL_TOKEN }}

Vercelのサイトでトークンを作成できるので、
作成してGithubのSecretに登録します。

GithubSecret

これでリポジトリにPUSHするだけで
自動デプロイされるようになりました!快適快適!
これをベースに個人アプリの開発を進めようと思います!

利用制限

無料アカウントだと制限がありますが検証には十分そうです。
Vercelプランに詳細があります。

VercelHobbyPlan

まとめ

さて、今回はVercelを使って
Serverless Function with Golangを試してみました!
さらに、手動デプロイが面倒なので、
VercelのデプロイをGithub Actionsで自動化しました。
無料プランでは制限はあるものの、Serverlessを簡単に試せるので、
Vercel Serverless Functionは魅力的なサービスだと感じました!

皆さんもぜひ試してみてください!
その際に本記事が参考になれば幸いです。