3
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Vercel FunctionsでGoのAPIサーバをデプロイする!

Posted at

はじめに

こんにちは、H×Hのセンリツ大好きエンジニアです。(同担OKです😉)

今回は、運用にお金を使いたくない人向けの味方「Vercel Functions」にステートレスなGoのAPIサーバをデプロイする方法をまとめました。

前提として、Vercel Functionsのデプロイに向いているものは以下の条件にクリアしたものになると思います😇

  • ステートレス(セッション管理などをしない)
  • 小規模なAPIサーバ
  • 一回のデータ取得に時間が掛からない

セットアップ

  1. Vercelのアカウント登録
  2. Vercel CLIのインストール
    • npmの場合、npm i -g vercel
  3. Vercelにログイン
vercel login

APIエンドポイント作成

ディレクトリ構成

これを元に、ご自身で構成を変えていただければと思います🫣

.
├── api # エンドポイント用
│   ├── articles # APIの例
│   │   └── index.go
│   └── index.go # 接続確認用
├── APIエンドポイントから実行される関数
│   ├── 様々
│   └── 色々
├── go.mod
├── go.sum
└── vercel.json # 設定ファイル

APIエンドポイント

まずは、Vercel Functionsが正しく動作するかの確認用に、/api/index.goを作成します。

api/index.go
package api

import (
	"fmt"
	"net/http"
)

func Handler(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintf(w, "<h1>Hello Vercel Functions!</h1>")
}

そして、各種エンドポイントを作成します。
動かす関数は用意しておいてください。

今回は、ルーティングと同じようにディレクトリを分けてます🥹

api/article/index.go
package articles

import (
	"net/http"
)

func Handler(w http.ResponseWriter, r *http.Request) {
	switch r.Method {
	case http.MethodGet:
		ArticlesPerPage(w, r) // 実行する関数はあらかじめ用意しておく
	default:
		w.WriteHeader(http.StatusMethodNotAllowed)
	}
}

設定ファイル作成

基本的に、デプロイするディレクトリのルートに設置します。

vercel.json
{
  "build": {
    "env": {
      "GO_BUILD_FLAGS": "-ldflags '-s -w'"
    }
  },
  "rewrites": [
    { "source": "/api", "destination": "/api" },
    { "source": "/api/articles", "destination": "/api/articles" }
  ],
  "headers": [
    {
      "source": "/api/(.*)",
      "headers": [
        { "key": "Access-Control-Allow-Origin", "value": "CORSを許可するURLを載せる" },
        { "key": "Access-Control-Allow-Methods", "value": "GET, OPTIONS" },
        { "key": "Access-Control-Allow-Headers", "value": "Content-Type, Authorization" }
      ]
    }
  ]
}

ここで注意して欲しいのですが、リファレンスにあるroutesは既に非推奨なので、rewritesを使用してルーティングを行います。🤯
(クエリパラメータを受け取るエンドポイントでも、特に意識せず上記のようにパスだけルーティングしても大丈夫です)

また、このAPIサーバのCORS設定はheadersで設定します。
headersを使用しないとCORSエラーになるので要注意!)

デプロイ

本番環境にデプロイをする場合、以下のコマンドを入力します。

vercel --prod

Error: queryA EREFUSED api.vercel.comが発生する場合、DNS設定を見直したり、接続しているWi-Fiを変更してみてください。

デプロイ後、アクセスすると正しい挙動になっているか確認します。
api/articlesを入力してみます。
スクリーンショット 2024-04-21 12.46.39.png

きちんと返ってきました。。。嬉しすぎて言葉が出ません。。。😮

注意点

POSTメソッドを行う場合、ブラウザによるCORSポリシーの一環であるプリフライトリクエスト(OPTIONSメソッド)が送信されてしまいます🥶

そのため、以下のように適切なCORSヘッダーを返すことで、POSTリクエストが正しく行われるようにします。

index.go
package articles

import (
	"net/http"
)

func Handler(w http.ResponseWriter, r *http.Request) {
	// OPTIONSリクエストへの対応
	if r.Method == http.MethodOptions {
		w.WriteHeader(http.StatusOK)
		return
	}

	switch r.Method {
	case http.MethodPost:
        // 何かしらのPOSTメソッド関数
	default:
		w.WriteHeader(http.StatusMethodNotAllowed)
	}
}

おわりに

今回は、節約したいエンジニアにとって素晴らしいツールである、Vercel Functionsの使用法を紹介しました。🥸

ですが、無料枠だと一回の関数が10秒以内に完了しないとtime outエラーになってしまうので、使用前に関数を分解する or 別のデプロイ先(AWS Lambdaなど)を検討する方が良いかと思います🥹

3
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?