注記
2023年2月22日現在、Vercelは、サーバーレスおよびエッジ関数をトリガーするために、組み込みのCronジョブを正式に提供しています。詳細については、ドキュメントを読んでください。この機能はベータ段階でのみ無料であることに注意してください。これは、一般的な可用性のための有料機能になります。つまり、GitHubアクションルートは完全に無料のオプションに関連し続けることを意味します。
githubアクションを備えたcronジョブnext.jsアプリケーションのvercel▲
Vercelプラットフォームはイベント駆動型であり、したがって実行中のサーバーを維持していないため、next.jsアプリケーションでAPIルートまたはサーバーレス関数の呼び出しを実際にスケジュールすることはできません。スケジュールされたCronジョブを提供する多くの既存のサービスがありますが、最終的にGitHubアクションは、GitHubに既に住んでいるプロジェクトとうまく統合しているため、完全に無料であるため、私のニーズに最適であると判断しました。
すべてのgithubアクションは、リポジトリのディレクトリ.github/workflows/にあり、yamlで記述されています。
.github/workflows/starter.yamlアクションを始めるのに役立つ最も基本的なワークフローです。
スケジュールされたイベントを使用すると、指定された間隔でタスクを実行できます。たとえば、提供されたワークフロー.github/workflows/scheduled.yaml 60分ごとにCurlでHTTP要求を実行します。
name : Hourly cron job
on :
schedule :
- cron : ' */60 * * * * '
jobs :
cron :
runs-on : ubuntu-latest
steps :
- name : Hourly cron job
run : |
curl --request POST
--url 'https://example.com/api/task'
--header 'Authorization: Bearer ${{ secrets.ACTION_KEY }}'Cronスケジュールの表現を書くのに苦労している場合は、Crontab Guruをご覧ください。
APIルートとサーバーレス関数は、Vercelのnext.jsでAPIを構築するための簡単なソリューションを提供します。フォルダーpages/api内のファイルは/api/*にマッピングされ、 pageの代わりにAPIエンドポイントとして扱われます。
ランタイムに関係なくサーバーレス関数を使用している場合は、プロジェクトのルートでファイルを/api/ディレクトリに配置する必要があります。
GitHubアクションでAPIルートとサーバーレス関数を安全にトリガーするには、API呼び出しのヘッダーに承認キーを提供する必要があります。
これは、GitHubリポジトリに暗号化された秘密を追加し、以前のコードSnippetに示すように、HTTPリクエストのヘッダーでそれらを渡すことで実現できます。 githubリポジトリにキーを追加するとともに、next.jsアプリケーション、できれば環境変数を介してアクセスする必要があります。
サンプルページpages/api/example.jsこの承認フローを実装しています。
export default function handler ( req , res ) {
const { APP_KEY } = process . env ;
const { ACTION_KEY } = req . headers . authorization . split ( " " ) [ 1 ] ;
try {
if ( ACTION_KEY === APP_KEY ) {
// Process the POST request
res . status ( 200 ) . json ( { success : 'true' } )
} else {
res . status ( 401 )
}
} catch ( err ) {
res . status ( 500 )
}
} TypeScriptにpages/api/example.tsを使用します。
import type { NextApiRequest , NextApiResponse } from 'next'
export default function handler ( req : NextApiRequest , res : NextApiResponse ) {
const { APP_KEY } = process . env ;
const { ACTION_KEY } = req . headers . authorization . split ( " " ) [ 1 ] ;
try {
if ( ACTION_KEY === APP_KEY ) {
// Process the POST request
res . status ( 200 ) . json ( { success : 'true' } )
} else {
res . status ( 401 )
}
} catch ( err ) {
res . status ( 500 )
}
}