LoginSignup
1
2

More than 5 years have passed since last update.

Serverlessで1サービス:多ファンクション管理

Last updated at Posted at 2016-12-09

・筆者なりの方法です。メジャーなやり方ではないかもしれません。
serverless@1.2.1時点でのメモ
・Lambdaプロキシ統合を使用(LAMBDA_PROXY, Lambda Proxy)

まずサービス作成

mkdir サービス名 && cd サービス名
sls create -t aws-nodejs

この時点での構成はきっとこんな感じ

階層1
./
event.json
handler.js
serverless.yml

APIGateway + Lambdaでいう「サービス」が
一体どれのことを言っているのかまでは調べきれていないが、
ここではAPIGatewayでの1APIプロジェクトとする。

関数準備

考える事

・LambdaはWebコンソールで関数の修正が可能。
→1ファイルに複数の関数を入れると、なんだか気持ち悪いことになりそう
→「1LambdaFunction = 1ファイル」がいいはず!

ということで、
こんな構成にする

階層1 階層2
./
event.json
handler.js
serverless.yml
function_dir1
      L get.js
event_get.json
function_dir2
      L post.js
event_post.json

関数ファイルを配備してくれるシェルを準備した

下記をサービス直下(serverless.ymlと同じ位置)に置いて実行してください。
※コードがしょぼいのは気にしないでください

function.sh
#!/bin/sh

errMsg1="Error:第2引数にはHTTPメソッドが必要です(例:get | post)"

myDir=$(cd $(dirname $0); pwd)
ymlPath=${myDir}"/serverless.yml"

# チェック
## serverless.ymlがある場所を起点とする
if [ ! -e ${ymlPath} ]
then
  echo "Error:サービスディレクトリ直下に配置してください"
  exit
fi

if [ -z ${1} ]
then
  echo "Error:第1引数には作成するディレクトリ名が必要です"
  exit
fi

fDir=${myDir}"/"${1}
fdFlg="true"

if [ -e ${fDir} ]
then
  if [ ! -d ${fDir} ]
  then
    echo "Error:作成予定のファイルが既に存在しており、ディレクトリでないようです"
    exit
  fi

  # ディレクトリ作成フラグ
  fdFlg="false"
fi

if [ -z ${2} ]
then
  echo ${errMsg1}
  exit
fi

if [ "get" != ${2} -a "post" != ${2} ]
then
  echo ${errMsg1}
  exit
fi

cFile=${fDir}"/"${2}".js"

if [ -e ${cFile} ]
then
  echo "Error:関数ファイルが既に存在しています"
  exit
fi

# 処理開始
## ディレクトリ作成
if [ "true" = ${fdFlg} ]
then
  mkdir -m 777 ${fDir}
fi

## 関数ファイル作成
fName="";
if [ "get" = ${2} ]
then
  fName=${1}"Get"
elif [ "post" = ${2} ]
then
  fName=${1}"Post"
fi

touch ${cFile}
chmod 777 ${cFile}

cat <<SETUP > ${cFile}
'use strict';

//External Libraries
//const hoge = require("hoge");

module.exports.${fName} = (event, context, callback) => {
  //Respomse Template
  var response = {
    statusCode: 200,
    headers: {"Access-Control-Allow-Origin" : "*"},
    body: null
  };

  //Response.Body Template
  var body = {
    message: 'successfully!',
    input: event,
    results: null
  };

  try {
    var results = '';

    body.results = results;
    response.body = JSON.stringify(body);
    callback(null, response);
  } catch(e) {
    //Exception
    response.statusCode = 500;
    body.message = e.message;
    response.body = JSON.stringify(body);

    callback(null, response);
  } finally {

  }
};
SETUP

# event.jsonも追加
eFile=${fDir}"/event_"${2}".json"
touch ${eFile}
chmod 777 ${eFile}

methodUpper=$(echo ${2} | tr [a-z] [A-Z])

cat <<SETUP > ${eFile}
{
"resource": "/${1}",
"path": "/${1}",
"httpMethod": "${methodUpper}",
"headers": null,
"queryStringParameters": null,
"pathParameters": null,
"stageVariables": null,
"requestContext": {
  "accountId": "xxxxxxxxxxxx",
  "resourceId": "xxxxxx",
  "stage": "test",
  "requestId": "xxxxxxxxxxxxxxxxxxx",
  "identity": {
    "cognitoIdentityPoolId": null,
    "accountId": "xxxxxxxxxxxx",
    "cognitoIdentityId": null,
    "caller": "xxxxxxxxxxxx",
    "apiKey": "xxxxxxxxxxxxxxxxxxx",
    "sourceIp": "xxxxxxxxxxxxxxxxxxxxx",
    "accessKey": "xxxxxxxxxxxxxxxxxxxx",
    "cognitoAuthenticationType": null,
    "cognitoAuthenticationProvider": null,
    "userArn": "arn:aws:iam::xxxxxxxxxxxx:xxxx",
    "userAgent": "Apache-HttpClient/4.5.x (Java/1.8.0_102)",
    "user": "xxxxxxxxxxxx"
  },
  "resourcePath": "/${1}",
  "httpMethod": "${methodUpper}",
  "apiId": "xxxxxxxxxx"
},
"body": null,
"isBase64Encoded": false
}
SETUP



# serverless.ymlに設定追加
cat <<SETUP >> ${ymlPath}
  ${1}-${2}:
    handler: ${1}/${2}.${fName}
    memorySize: 128
    timeout: 10
    events:
      - http:
          path: ${1}
          method: ${2}
SETUP

関数配備シェルを実行しよう

実行方法
sh function.sh 関数ディレクトリ HTTPメソッド
sh function.sh list get

上記例を実行すると
構成は以下になる。

階層1 階層2
./
event.json
handler.js
serverless.yml
function.sh
list
      L get.js
event_get.json

serverless.ymlにも設定が追加されているので、
すぐデプロイ出来る状態になります。
※ymlの構成までは見てないので、適時インデントなどは直してください

デプロイしよう

# 一度もデプロイされたことのないものは、単一でアップできないため、
# 初回は必ずサービスまるごとデプロイ
sls deploy

# 一度でもデプロイされていれば単一アップ可
# ※関数名はserverless.ymlで記載したもの
sls deploy function -f 関数名※

最後に

上記で作成すると次のようなルールになります。

説明
サービス名 serverless.ymlに設定したもの
パス 関数ディレクトリと同じ
HTTPメソッド function.shの第2引数で指定したもの
LambdaFunction名 サービス名-ステージ-パス-HTTPメソッド
js関数名 パス+HTTPメソッド
例:listGet、indexPost
serverless.ymlの関数名 パス-HTTPメソッド
1
2
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
1
2