はじめに
こんにちは!!会津大学学部二年のHAMADAです。
11月も後半に差し掛かり、寒さに苦しんでいる今日この頃です。
今回は、AWSのハンズオンGoで書いて入門したお話です。
動機・目的
今までAWS、GCP、Firebaseなどに対する得体の知れなさを持っていましたが、私が作りたいものや、学びたい技術とは切っても切れないものなので思い切って挑戦してみました!! 足りないポイント、間違った解釈があるかと思いますが、暖かい目でみていただけると嬉しいです。
使った技術
参考にしたハンズオンリンク
手順
- AWS Lambdaを構築、Amazon Translateを呼び出す。
- API Gateway を用いて Lambda Function と組み合わせてWeb APIを作成する。
- Amazom DynamoDB を用いて翻訳したデータを保存する。
1. AWS Lambdaを構築、Amazon Translateを呼び出す
awsにログインして、Lamdaを開きます。
アカウントの作成方法やセキュリティの設定などは機会があれば書こうと思います。
オレンジの関数の作成を押します。
今回は1から作成を選択し、関数名を自分で記入しランタイムをGo 1.xにしました。
pythonやNode.jsではAWS上でプログラムが書けるのですが、Goは対応していないのでvscodeでプログラムを書いてfunction.zipファイルをアップロードします。
書いたコード
//Translate/transltate.go
package translate
import (
"fmt"
"log"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/translate"
)
func TranslateFunc() {
InputText := "日本語だよ!こっちは英語"
InputLang := "ja"
OutputLang := "en"
sess := session.Must(session.NewSession())
trans := translate.New(sess)
result, err := trans.Text(&translate.TextInput{
SourceLanguageCode: aws.String(InputLang),
TargetLanguageCode: aws.String(OutputLang),
Text: aws.String(InputText),
})
if err != nil {
log.Print("おかしいぜ")
}
fmt.Println(*result.TranslatedText)
}
//handler.go
package main
import (
"github.com/ahmos0/goLambdaFirst.git/Testgreeting"
"github.com/ahmos0/goLambdaFirst.git/Translate"
"github.com/aws/aws-lambda-go/lambda"
)
func exucuteFunc() {
Translate.TranslateFunc()
}
func main() {
lambda.Start(exucuteFunc)
}
InputTextの日本語を英語に変換します。InputLangは今回日本語なので"ja"。これをOutputLangは"en"にして変換しています。
その後Translateのセッションを確立しています。
trans.Textに翻訳の対象となる言語(今回は日本語)、翻訳先の言語(今回は英語)、対象となる文字列を translate.TextInput で翻訳与えてあげます。
handler.goから実行します。
Lambda上にzipファイルとしてあげる際に、以下を実行しました。
go build
GOOS=linux go build -o handler handler.go
zip function.zip handler
普段通りbuildしてあげてから、handlerを作成します。これは、Lambda関数で呼び出す主軸のようなものですね。その後、handlerをzipにしてあげればOKです。
テストのやり方などは、最終checkの段階に書こうと思います。
2. API Gateway を用いて Lambda Function と組み合わせてWeb APIを作成する
右上のAPIを作成から作ります。
REST APIを選びます。
設定は上記のようにしました。
リソースの作成から/translate
メソッドの作成からGETを作成します。
GETの統合リクエストを選択し、以下のように設定。
書いたコード
//Translate/translate.go
package Translate
import (
"fmt"
"log"
"github.com/aws/aws-lambda-go/events"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/translate"
)
var OutputText string
func TranslateFunc(req events.APIGatewayProxyRequest) string {
InputText := req.QueryStringParameters["InputText"]
InputLang := "ja"
OutputLang := "en"
sess := session.Must(session.NewSession())
trans := translate.New(sess)
log.Println(InputText + "これです")
result, err := trans.Text(&translate.TextInput{
SourceLanguageCode: aws.String(InputLang),
TargetLanguageCode: aws.String(OutputLang),
Text: aws.String(InputText),
})
if err != nil {
log.Print("おかしいぜ")
}
OutputText := *result.TranslatedText
return OutputText
}
//handler.go
package main
import (
"github.com/ahmos0/goLambdaFirst.git/Testgreeting"
"github.com/ahmos0/goLambdaFirst.git/Translate"
"github.com/aws/aws-lambda-go/events"
"github.com/aws/aws-lambda-go/lambda"
)
type Response struct {
StatusCode int `json:"statusCode"`
Body string `json:"body"`
}
func ExucuteFunc(request events.APIGatewayProxyRequest) (Response, error) {
OutputText := Translate.TranslateFunc(request)
return Response{
StatusCode: 200,
Body: OutputText,
}, nil
}
func main() {
lambda.Start(ExucuteFunc)
}
events.APIGatewayProxyRequestで文字列を確保し、Translate.TranslateFuncで翻訳しています。QueryStringParamerters["InputText"]で元の日本語文を取得しています。
できているかの確認は、今回も最後のチェックで説明します。
3. Amazom DynamoDB を用いて翻訳したデータを保存する
DynamoDBでテーブル作成をします.
右上のテーブル作成から作ります。
テーブルの作成は以下のように設定しました。
テーブルの項目は、timestamp、InputText、OutputTextを作りました。
書いたコード
//database/DynamoDB.go
package database
import (
"fmt"
"time"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/dynamodb"
"github.com/aws/aws-sdk-go/service/dynamodb/dynamodbattribute"
)
type Item struct {
TimeStamp string `json:"timestamp" dynamodbav:"timestamp"`
InputTextj string `json:"inputtext" dynamodbav:"InputText"`
OutputTextj string `json:"outputtext" dynamodbav:"OutputText"`
}
func OperateDB(InputText string, OutputText string) {
sess := session.Must(session.NewSessionWithOptions(session.Options{
SharedConfigState: session.SharedConfigEnable,
}))
fmt.Println(InputText)
fmt.Println(OutputText)
dynamo := dynamodb.New(sess)
t := time.Now()
item := Item{
TimeStamp: *aws.String(t.String()),
InputTextj: *aws.String(InputText),
OutputTextj: *aws.String(OutputText),
}
av, err := dynamodbattribute.MarshalMap(item)
if err != nil {
fmt.Println(err.Error())
}
tableName := "translate-history"
input := &dynamodb.PutItemInput{
TableName: aws.String(tableName),
Item: av,
}
_, err = dynamo.PutItem(input)
if err != nil {
fmt.Println(err.Error())
}
}
//Translate/translate.go
package Translate
import (
"fmt"
"log"
"github.com/ahmos0/goLambdaFirst.git/database"
"github.com/aws/aws-lambda-go/events"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/translate"
)
var OutputText string
func TranslateFunc(req events.APIGatewayProxyRequest) string {
InputText := req.QueryStringParameters["InputText"]
InputLang := "ja"
OutputLang := "en"
sess := session.Must(session.NewSession())
trans := translate.New(sess)
log.Println(InputText + "これです")
result, err := trans.Text(&translate.TextInput{
SourceLanguageCode: aws.String(InputLang),
TargetLanguageCode: aws.String(OutputLang),
Text: aws.String(InputText),
})
if err != nil {
log.Print("おかしいぜ")
}
OutputText := *result.TranslatedText
fmt.Println(OutputText + "わーい")
database.OperateDB(InputText, OutputText) //ここでdatabaseに追加する
return OutputText
}
handler.go は前と同じコードです。
実際にできたものを確認していきます
API Gatewayからアクション>APIのデプロイを選択
このようにします。
GETを選択し、URLの呼び出しというところのリンクに飛びます.
すると今のままでは、Internal server errorが返ってきます。
{"message": "Intenal sever error" }
URLの末尾をdev/translate?InputText=やったか?
のように指定すると
did you do it?
のように返ってきます。
DynamoDBの方には、タイムスタンプ、入力した日本語、返ってきた英語が保存されます。
こんな感じですね。
テストのやり方
テストイベントを作成して、右上のテストからテストを実行します。
成功すれば、この上に成功と緑色で表示されログを見れます。
今回は、queryStringParametersの中身だけ変更しました。そのほかはAPICallのテンプレです。
今回のgithub repository
感想と展望
AWSに触れるのは初めてでさまざまな難題にも悩まされましたがなんとか完走できてよかったです。結構詰まることもあったので、できた時は快感でした!!!一つずつ積み重ねていくことの重要性を実感できました。またpythonで話を聴きながらgoで書くというのが自分の力で実装できたという自信にもつながったのでよかったです。ここまで読んでいただきありがとうございました。拙い部分も多いので、間違った点などあればご指摘いただけると幸いです。次回またよろしくお願いいたします!!!
所属サークル
私のTwitter
私のgithub
参考リンク