💡

Lambdaを使用して特定の時間にAPIを叩く処理を実現する

2024/09/10に公開

この時間になったらAPIを叩いてページの情報を更新するような処理を実現したいなーと思ったことはありませんか?前から疑問に思いつつ実現できていなかったので、今回まとめてみました。チュートリアル形式になってるのでみながらやって貰えばできると思います
これを応用すれば
・1日ごとにページの情報を更新する
・自分が定めた時間にAPIを叩くことで手間を省く
ことができると思います

開発環境

OS: mac os
バックエンド:go(他の言語でももちろん大丈夫です)
インフラ:AWS lambda,S3,eventbridge,cloudformation,cloudwatch

apiを叩くプログラムを作成

まずはファイルを作成しましょう。vscodeを開き、main.goという名前のファイルを作ります。
そしてそこに以下のコードを貼り付けましょう。
以下はgoでapiを叩くサンプルコードです。

package main

import (
    "fmt"
    "io"
    "net/http"
    "net/url"
    "time"
)

func callAPI() {
    baseURL := "https://zipcloud.ibsnet.co.jp/api/search"
    postalCode := "1000001" // ここで検索したい郵便番号を指定します

    // クエリパラメータを含めてURLを作成
    queryURL := fmt.Sprintf("%s?zipcode=%s", baseURL, url.QueryEscape(postalCode))

    client := &http.Client{
        Timeout: 30 * time.Second,
    }

    req, err := http.NewRequest("GET", queryURL, nil)
    if err != nil {
        fmt.Println("Error creating request:", err)
        return
    }

    res, err := client.Do(req)
    if err != nil {
        fmt.Println("Error making request:", err)
        return
    }
    defer res.Body.Close()

    body, err := io.ReadAll(res.Body)
    if err != nil {
        fmt.Println("Error reading response:", err)
        return
    }

    // レスポンス内容を表示
    fmt.Println(string(body))
}

func main() {
    // APIを呼び出す
    callAPI()
}

これが完了したら以下のコマンドをターミナルで実行してbootstrapというファイルを作成してください。

GOOS=linux GOARCH=amd64 go build -o bootstrap main.go

なぜこれを作成したのかは後で説明します。そしてこの2つのファイルをzipファイルに圧縮します。
2つのファイルを選択した状態で「圧縮する」を選択してください。そしてそのzipファイルの名前はgo_handler.zipとしておいてください。

次にAWSのマネジメントコンソールからS3を開き、「バケットを作成」→「アップロード」からgo_handler.zipをアップロードしてください。

Cloudformationにアップロードするファイルを作成

これを使えばAWSのリソースを自動で作成してくれます。今回初めて使いましたがすごく便利、、
まずはtemplate.yamlというファイルを作成します。(vscodeで作れば大丈夫です)
そしてそこに以下のコードを貼り付けます。

AWSTemplateFormatVersion: "2010-09-09"
Description: "Sample of CloudFormation template for deploying a Lambda function using Go."

Resources:
  HelloSample:
    Type: AWS::Lambda::Function
    Properties:
      Code:
        S3Bucket: "先ほど作成したバケット名" 
        S3Key: "go_handler.zip"  # アップロードしたZIPファイル名
      Description: "Test deploy Lambda template using Go"
      FunctionName: "test_lambda_function"
      Handler: "bootstrap"                 # LambdaのHandlerとしてbootstrapを指定
      Role:
        Fn::GetAtt:
          - LambdaExecutionRole
          - Arn
      Runtime: "provided.al2"              # AWS提供のカスタムランタイムを使用
      MemorySize: 128                      # メモリサイズ(任意で変更可能)
      Timeout: 600                          # タイムアウト時間(秒)
  
  LambdaExecutionRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: "Allow"
            Principal:
              Service:
                - "lambda.amazonaws.com"
            Action:
              - "sts:AssumeRole"
      Policies:
        - PolicyName: "LambdaBasicExecution"
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Effect: "Allow"
                Action:
                  - "logs:CreateLogGroup"
                  - "logs:CreateLogStream"
                  - "logs:PutLogEvents"
                Resource: "*"

先ほどbootstrapを作成したのはここで作成するlambda関数のhandlerをbootstrapにする必要があるからです。cloudformationを使用するにはランタイム(goを実行するための環境)をprovided.al2にする必要があり、その場合handlerはbootstrapにする必要があったのでbootstrapを作成しました。

それではこのファイルをcloudformationにアップロードします。「cloudformation」→「スタック」→「スタックの作成」→「新しいリソースの使用(標準)」と進みます。
写真のようにファイルをアップロードします。

次に進み、任意の名前をつけます。あとの設定は全てデフォルトで大丈夫です。最後のページの一番下で写真のようにチェックをつけてください。

そして作成してください。

そしてlambdaのコンソールに移動すると関数が作成されているはずです。ではあとはこれにevent bridgeを使用してトリガーを作成すれば完了です。

eventbridge設定

まずは設定前にアップロードしたコードをテストして問題なくログが表示されることを確認しましょう。写真のようにevent名にテストと入力してあとはデフォルトで「テスト」ボタンを押しましょう。

緑色で成功と表示されていればOKです

そして次にログをcloudwatchで確認するために「モニタリング」タブに移りましょう。するとアクセス権限がないことが上のほうで指摘されているはずです。そこに書いてあるAWSLambdaBasicExecutionRoleポリシーを実行ロールにアタッチします。「設定」タブに移動→アクセス権限で「ロール名」と書かれたURLをクリックしてください。
するとIAMロールコンソールに移動します。そして写真のように「ポリシーをアタッチ」をクリックします。検索窓にAWSLambdaBasicExecutionRoleを入力し、チェックを入れて「許可を追加」をクリックします。これでログがcloudwatchで表示されるようになりました。

ではeventbridgeの設定を行なっていきます。「トリガーを追加」をクリックしてeventbridgeを選択して次に進みます。そして写真のように設定します。今回はログが表示されることをすぐ確かめるために「3分周期で実行」するようにしました。

そしてcloudwatchに移動して3分後にログが表示されていることを確認できれば成功です!お疲れ様でした。あとは「スケジュール式」に「cron(0 15 * * ? *)」と入力すれば毎日0時にAPIを叩いてくれる処理の完成です。

eventbridgeの設定方法の説明は以下の方の説明がわかりやすいです
https://predora005.hatenablog.com/entry/2021/05/05/190000

Discussion