Help us understand the problem. What is going on with this article?

Serverless Framework で 自身のAPIのURLを取得したい

はじめに

Serverless FrameworkでAPI Gatewayを利用した際に
死活監視やなんらかの目的で
内部的にAPIを呼び出したい場合があるかと思います。

ただ、デプロイされたあとにURLを確認し
Lambdaの環境変数に・・・などはちょっと面倒くさいので
serverless.yml内だけで設定できないかやってみました。

customにてURLを生成

本題部分です、API Gatewayで生成されるURLを文字連結します。
これでAPI GatewayのURLが生成できます。

custom:
  region: ap-northeast-1
  stage: ${opt:stage,"default"}
  my_url:
    {
      "Fn::Join":
        [
          "",
          [
            "https://",
            { "Ref": "ApiGatewayRestApi" },
            ".execute-api.${self:custom.region}.amazonaws.com/${self:custom.stage}/",
          ],
        ],
    }

customで作成したURLをLambdaのenvironmentに設定

折角なので実際にAPIを叩いてみます。
※言語はnodeを前提として記述してます。

APIを叩いてくれるshikatsukannshi
shikatsukannshiに叩かれるtergetA,tergetBを作成します。

shikatsukannshiが30分に1回立ち上がってtergetA,tergetBにアクセスするような
感じで作成しています。

functions:
  shikatsukannshi:
    handler: shikatu/handler.main
    environment:
      MY_URL: ${self:custom.my_url}
    events:
      - schedule: rate(30 minutes)
  tergetA:
    handler: api/handler.main
    environment:
      MY_NAME: A
    events:
      - http:
          path: target/a
          method: get
  tergetB:
    handler: api/handler.main
    environment:
      MY_NAME: B
    events:
      - http:
          path: target/b
          method: get

これでshikatsukannshiLambdaの環境変数MY_URL内に
自身と紐づくAPI GatewayのURLが入力されるはずです。

serverless.yml全体としては以下のようなものを作成しました。

service: qiita-sample

custom:
  region: ap-northeast-1
  stage: ${opt:stage,"default"}
  my_url:
    {
      "Fn::Join":
        [
          "",
          [
            "https://",
            { "Ref": "ApiGatewayRestApi" },
            ".execute-api.${self:custom.region}.amazonaws.com/${self:custom.stage}/",
          ],
        ],
    }

provider:
  name: aws
  runtime: nodejs12.x
  memorySize: 128
  region: ${self:custom.region}

functions:
  shikatsukannshi:
    handler: shikatu/handler.main
    environment:
      MY_URL: ${self:custom.my_url}
    events:
      - schedule: rate(30 minutes)
  tergetA:
    handler: api/handler.main
    environment:
      MY_NAME: A
    events:
      - http:
          path: target/a
          method: get
  tergetB:
    handler: api/handler.main
    environment:
      MY_NAME: B
    events:
      - http:
          path: target/b
          method: get

apiと監視用Lambdaの作成

ますはAPIから
環境変数から自分の名前を取得して返すだけのAPI

api/handler.js
module.exports.main = async (event) => {
    return {
        body: 'Qiitaサンプル:' + process.env['MY_NAME'],
        statusCode: 200
    }
}

そして監視用のLambda
こっちもリクエストを投げ結果をログに出すだけのもの

shikatu/handler.js
module.exports.main = (event) => {
    const request = require("request");
    const url = process.env['MY_URL']

    // 監視A
    request.get({
        url: url + 'target/a'
    }, function (error, response, body) {
        console.log(body);
    });

    // 監視B
    request.get({
        url: url + 'target/b'
    }, function (error, response, body) {
        console.log(body);
    });
}

結果確認

デプロイしログを確認します

image.png

無事APIへアクセスできているようです。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away