ちょっと話題の記事

ojichatをサーバーレスAPI化した

2021.03.10

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

ojichatをAPI化する必要があったため、AWS SAMを利用してサーバーレスな構成で実装してみました。

概要

ojichat とは、READMEにも書かれているとおり、「おじさんがLINEやメールで送ってきそうな文を生成」してくれる物となります。

既にDockerで環境を汚さずに利用する事も出来ますが、今回はAPI化する必要がありましたので、簡単なLambda関数を作ってみました。

作ったもの

AWSの構成は下記のように、シンプルなAPI Gateway + Lambdaの構成となります。

Goで次のように、BodyからNameを取得して greymd/ojichat/generator を利用しておじさん文章を生成して返却する簡単なコードを書きました。

package main

import (
	"encoding/json"
	"github.com/aws/aws-lambda-go/events"
	"github.com/aws/aws-lambda-go/lambda"
	"github.com/greymd/ojichat/generator"
)

type Payload struct {
	Name string `json:"name"`
}

type Response struct {
	Message string `json:"message"`
}

func handler(request events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error) {
	var payload Payload
	err := json.Unmarshal([]byte(request.Body), &payload)
	if err != nil {
		return events.APIGatewayProxyResponse{
			Body:       err.Error(),
			StatusCode: 500,
		}, err
	}

	config := generator.Config{
		TargetName:       payload.Name,
		EmojiNum:         4,
		PunctuationLevel: 0,
	}

	ojiResult, err := generator.Start(config)
	if err != nil {
		return events.APIGatewayProxyResponse{
			Body:       err.Error(),
			StatusCode: 500,
		}, err
	}

	res := Response{
		Message: ojiResult,
	}

	jsonResult, _ := json.Marshal(res)

	return events.APIGatewayProxyResponse{
		Body:       string(jsonResult),
		StatusCode: 200,
	}, nil
}

func main() {
	lambda.Start(handler)
}

また、API GatewayやLambdaの構成管理はAWS SAMを使っていて、簡単なYAMLで構成管理できるようにしています。

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: serverless-ojichat
Globals:
  Function:
    Timeout: 5

Resources:
  OjiFunction:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: oji/
      Handler: oji
      Runtime: go1.x
      Tracing: Active
      Events:
        CatchAll:
          Type: Api
          Properties:
            Path: /oji
            Method: POST
Outputs:
  OjiAPI:
    Description: API Endpoint URL
    Value: !Sub "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/oji"

コードなどは mokocm/serverless-ojichatで公開しています。

利用方法

デプロイにはAWS SAMを利用するため、インストールしていない場合は下記ドキュメントに記載の通りインストールを行います。

https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-install.html

デプロイ手順は次の通りです。

git clone https://github.com/mokocm/serverless-ojichat/
cd serverless-ojichat/

sam build
sam deploy --guided

Configuring SAM deploy
======================

	Looking for config file [samconfig.toml] :  Not found

	Setting default arguments for 'sam deploy'
	=========================================
	Stack Name [sam-app]: serverless-ojichat
	AWS Region [us-east-1]: ap-northeast-1
	#Shows you resources changes to be deployed and require a 'Y' to initiate deploy
	Confirm changes before deploy [y/N]: y
	#SAM needs permission to be able to create roles to connect to the resources in your template
	Allow SAM CLI IAM role creation [Y/n]: y
	OjiFunction may not have authorization defined, Is this okay? [y/N]: y
	Save arguments to configuration file [Y/n]: y
	SAM configuration file [samconfig.toml]: 
	SAM configuration environment [default]:

SAMでのデプロイ作業が終わると、Outputs枠にAPI GatewayのEndpoint URLが表示されます。

CloudFormation outputs from deployed stack

Key                 OjiAPI                                                                                                                                                                                                        
Description         API Endpoint URL                                                                                                                                                                                              
Value               https://66tc6jmsxg.execute-api.ap-northeast-1.amazonaws.com/Prod/oji                                                                                                                                          


Successfully created/updated stack - serverless-ojichat in ap-northeast-1

こちらのURLを利用して、curlで適当な名前をPOSTしておじさん文章を生成してみましょう。

curl -X POST https://66tc6jmsxg.execute-api.ap-northeast-1.amazonaws.com/Prod/oji  -d '{"name": "ぴよ"}'
{"message":"ぴよちゃん、お疲れ様〜??♥ 今日はどんな一日だった?僕は、すごく心配だよ(-_-;)?( ̄Д ̄;;そんなときは、美味しいもの食べて、元気出さなきゃだね?"}

まとめ

今回Goを使ったAPI Gateway + Lambdaの構成を初めて組んでみましたが、数時間で簡単に作る事ができました。

AWS SAMはPython、Nodeくらいしか使えないのかと思ってましたが、Goも行けることを初めて知りました。

突然ojichatをAPI化する必要が出てきてもすぐ使えるように、GitHubで公開していますので、ojichatをAPI化する際は是非お使いください。

誰かにお役に立てれば幸いです。