Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
🐭 Lambda関数をGoで実装してみた話
Search
⛵️ 長谷川 広樹 🐬
March 26, 2021
Programming
1k
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
🐭 Lambda関数をGoで実装してみた話
社内LTにて、Goを布教しようと試みましたʕ◔ϖ◔ʔ
⛵️ 長谷川 広樹 🐬
March 26, 2021
More Decks by ⛵️ 長谷川 広樹 🐬
See All by ⛵️ 長谷川 広樹 🐬
『Kubernetes ☸️ で実践する Platform Engineering 』を最高速度で読み抜いたる!!👊🏻
hiroki_hasegawa
1
260
♾️ マルチプロダクトの巨大組織でマイクロサービス開発を支えるCICDプラットフォーム設計
hiroki_hasegawa
5
4.9k
🐙 KubernetesのマルチテナントパターンとArgoCDの実践テナント設計
hiroki_hasegawa
4
3.9k
🧑🚀 tfstate の分割パターンとディレクトリ構成への適用
hiroki_hasegawa
8
8.9k
⛵️ Istioのサービス間通信を実現するサービスディスカバリーの仕組み
hiroki_hasegawa
3
7.6k
🔍 可観測性に入門しよう
hiroki_hasegawa
1
1.2k
🏗️ ドメイン駆動設計と依存性逆転の原則
hiroki_hasegawa
14
10k
🤝🏻 依存関係と依存オブジェクト注入
hiroki_hasegawa
2
1.4k
🐭 Goに入門しよう
hiroki_hasegawa
0
790
Other Decks in Programming
See All in Programming
Intent as Code
shoppingjaws
6
1.1k
技術的負債を組織課題として解く-増えすぎたマイクロサービスとの戦い-
reimaru
1
2.6k
JPUG勉強会 OSSデータベースの内部構造を理解しよう(第2回)
oga5
0
290
20260914 AIエージェント時代のPlatform Engineering LLM基盤とプロダクトの責務境界線
kanfab1
7
2.3k
AWS CDKのカスタムリソースでContinuum(旧Security Agent)を実装した話 | Implementing Continuum (formerly Security Agent) via AWS CDK Custom Resource
akihisaikeda
2
120
App Storeの外へ──日本のiOSサイドローディング入門 for iOSDC Japan 2026
yuukiw00w
0
290
SONY CISC-NEWS NWS-1750 + NWB-225 フレームバッファの NetBSD/news68k ドライバ実装 / OSC2026Hiroshima
tsutsui
0
160
ハーネス設計入門 〜 基礎知識の整理から実務へのステップアップ 〜
kinopeee
20
20k
[Rails World 2026] Durable orchestration on Rails: from continuation to workflow
palkan
1
410
モデルのリファクタリングが難しいと思ったら、そもそも複雑だったのはビジネス仕様だった ? / is-the-business-domain-the-real-complexity
hatsu38
0
430
Workers Cache を知る
syumai
0
320
JAWS-UG 東京支部が始める、JAWS-UG支部コラボ / JAWS-UG lunchtime LT Collaboration
y0hgi
0
170
Featured
See All Featured
Have SEOs Ruined the Internet? - User Awareness of SEO in 2025
akashhashmi
0
510
How to train your dragon (web standard)
notwaldorf
97
6.8k
Navigating Weather and Climate Data
rabernat
0
540
The SEO Collaboration Effect
kristinabergwall1
1
580
Build The Right Thing And Hit Your Dates
maggiecrowley
39
3.5k
Tell your own story through comics
letsgokoyo
1
1.1k
Beyond borders and beyond the search box: How to win the global "messy middle" with AI-driven SEO
davidcarrasco
3
270
The Curious Case for Waylosing
cassininazir
1
550
The Mindset for Success: Future Career Progression
greggifford
PRO
0
520
[RailsConf 2023 Opening Keynote] The Magic of Rails
eileencodes
31
10k
Practical Tips for Bootstrapping Information Extraction Pipelines
honnibal
25
2.1k
Everyday Curiosity
cassininazir
0
340
Transcript
Lambda関数を Goで実装してみた話 株式会社ユニクエスト 長谷川広樹 github.com/hiroki-it @Hiroki__IT
自己紹介 ▼ お仕事 最近:クラウドインフラ、IaC、CICD、... 以前:DDD ▼ 関心のある技術領域 ・クラウドインフラ ・IaC ・DDD
github.com/hiroki-it @Hiroki__IT 長谷川 広樹 (はせがわ ひろき) 株式会社ユニクエスト
目次 ▪ Goの概要 ▪ ディレクトリ構造 ▪ Goの基本文法 ▪ Goファイルの要素 ▪
Lambdaを使用した通知処理
Goの概要(1) 手続き型言語のため,オブジェクト機能なし. 第9回 UMTPモデリング技術 ワークショップ https://umtp-japan.org/
Goの概要(2) 静的型付け言語のため,ソースの実行前にビルドが必要. ビルドの成果物 = アーティファクト https://www.atmarkit.co.jp/ait/articles/1105/23/news128.html
Goの概要(3) 実装方法が強制されるため,可読性が高く,後続者が開発がしやすい 実装がスケーリングしやすい 静的解析のルールが厳しいため,バグを事前に見つけられる バグが許されない基盤部分に適している
ディレクトリ構造(1) ・bin ビルドされたアーティファクト(バイナリファイル)を配置. ・pkg アーティファクトとは別に生成されるファイルを配置. ・src ソースコードを配置. $GOPATH # 決まりは無いが,$HOME/go
とすることが多い ├── bin ├── pkg └── src
ディレクトリ構造(2) notify-slack-of-amplify-events # srcに相当 │ ├── build │ └── Dockerfile ├──
cmd │ ├── main.go │ ├── controllers │ ├── entities │ └── usecases │ ├── config ├── test ├── .air.toml ├── docker-compose.yml ├── go.mod └── go.sum https://github.com/hiroki-it/notify-slack-of-amplify-events ディレクトリ構造ベストプラクティス:https://github.com/golang-standards/project-layout
ディレクトリ構造(3) ・build Dockerfileを配置. ・cmd main.goファイルや,サブmainパッケージを配置. src # ソースコードを配置 ├── build
└── cmd ├── main.go ├── controllers ├── entities └── usecases
Goファイルの要素(1) package <パッケージ名> // 名前空間の宣言 import "<パッケージ名>" // パッケージの読み込み func
Xxx(){ // 関数 } ・一つのディレクトリ内では一つのパッケージ名のみ. ・関数名は,頭文字が大文字だとパブリック,小文字だとプライベートになる.
Goファイルの要素(2) package main func main(){ } ・エントリポイントは,cmdディレクトリまたはその子ディレクトリに配置. ・パッケージ名はmain. ・関数名はmain.
Goファイルの要素(3) func Division(x int, y int) (int, int) { //
商を計算する. quotient := x / y // 余りを計算する. remainder := x % y // 商と余りを返却する. return quotient, remainder } ・引数と返却値の型に厳格. ・複数の値を返却可能.
Goの環境構築(1) FROM golang:1.15 ENV CGO_ENABLED=0 # C言語製のライブラリの有効化 ENV GOOS=linux #
Goが稼働するOS(※GoはOSに縛られない) ENV GOARCH=amd64 # CPUアーキテクチャ ENV GO111MODULE=on # go.modの有効化 WORKDIR ${GOPATH}/src 最近,『go.mod(≒ composer.json)』『go.sum(≒ composer.lock)』が導入
Goの環境構築(2) module github.com/hiroki-it/notify-slack-of-amplify-events go 1.15 require ( # プロトコルを除いたURLとバージョンでパッケージを必ず指定 github.com/aws/aws-lambda-go
v1.23.0 github.com/stretchr/testify v1.7.0 ) replace ( # mainパッケージの共通部品も,インターネット上に存在することを強制 github.com/hiroki-it/notify-slack-of-amplify-events/cmd/entities/xxx => /cmd/entities/xxx ) あらゆるパッケージはインターネット上にリリースされるべきという思想 go.modファイル
Goの環境構築(3) # インストールのキャッシュを活用するためにコピーしておく. COPY go.mod go.sum ./ # パッケージをインストールする. RUN
go get -u github.com/cosmtrek/air \ && go mod download -x COPY . . ・mod downloadコマンド go.modファイルに実装したパッケージをインストール
Goの環境構築(4) https://github.com/cosmtrek/air ソースコード変更の度にビルドを行うホットリロードツール『Air』
Goの環境構築(5) # ビルドのアーティファクトを/go/binに配置する. RUN go build -x -o go/bin ./cmd
CMD ["/go/bin/cmd"] ・cmdディレクトリ ベストプラクティスに則り,cmdディレクトリにソースコードを配置. ・buildコマンド ソースコードをビルドし,binディレクトリにアーティファクトを配置.
Lambdaを使用した通知処理(1) package main import ( "github.com/aws/aws-lambda-go/lambda" "github.com/hiroki-it/notify-slack-of-amplify-events/cmd/controllers/handler" ) // lambdaパッケージからStartメソッドをコール
func main() { lambda.Start(handler.HandleRequest) // slackパッケージのHandler関数をコール } main.goファイル
Lambdaを使用した通知処理(2) func HandleRequest(request Request) error { var event eventbridge.Event //
EventBridgeから転送されたJSONを受信し,構造体にマッピングします. err := json.Unmarshal([]byte(request.Records[0].EventBridge.Event), &event) slackClient := slack.NewSlackClient() message := slackClient.BuildMessage(event) return slackClient.PostMessage(message) } 構造体?? 構造体とJSONのマッピング?? handler.goファイル
Lambdaを使用した通知処理(3) type Person struct { Name string // 構造体が持つデータの型 }
func main() { person := Person{"Hiroki"} // 構造体にデータを設定する. fmt.Printf("%#v\n", person.Name) // "Hiroki" } ・構造体とは,メソッドは持たず,データのみを持つもの. ・関数に構造体を関連付けることで,オブジェクトを擬似的に表現可能.
Lambdaを使用した通知処理(4) type Person struct { // 構造体 Name string }
func (person Person) SetName(name string) { // セッター関数を構造体に関連付ける person.Name = name } func (person Person) GetName() string { // ゲッター関数を構造体に関連付ける return person.Name } func main() { person := Person{Name: "Gopher"} person.SetName("Hiroki") // セッター関数で値を上書きする fmt.Printf("%#v\n", person.GetName()) // "Gopher" }
Lambdaを使用した通知処理(5) type Event struct { Version string `json:"version"` ... Detail
struct { AppId string `json:"appId"` BranchName string `json:"branchName"` JobId string `json:"jobId"` JobStatus string `json:"jobStatus"` } `json:"detail"` } JSONと構造体で相互変換するため,構造体の定義時にJSONマッピングが必要 { "event": { "version": "0", ... "detail": { "appId": "dd31ugx1agx51", "branchName": "feature/293_deploy_to_amplify", "jobId": "2", "jobStatus": "SUCCEED" } } }
Lambdaを使用した通知処理(6) func Handler(request Request) error { var event eventbridge.Event err
:= json.Unmarshal([]byte(request.Records[0].EventBridge.Event), &event) slackClient := slack.NewSlackClient() // 通知メッセージのJSONを構成します. message := slackClient.BuildMessage(event) return slackClient.PostMessage(message) } https://github.com/hiroki-it/notify-slack-of-amplify-events/blob/develop/cmd/ buildMessageメソッドで構成される構造体は,slackのtype.goの閲覧を推奨
Lambdaを使用した通知処理(7) func postMessage(message Message) error { json, err := json.Marshal(message)
// マッピングを元に,構造体をJSONに変換する. request, err := http.NewRequest( // リクエストメッセージを定義する. "POST", os.Getenv("SLACK_API_URL"), bytes.NewBuffer(json), ) ... ・JSONをMessage構造体にマッピング. ・POSTリクエストの必要なパラメータを設定. post.goファイル
Lambdaを使用した通知処理(8) … request.Header.Set("Content-Type", "application/json") // ヘッダーを定義する. request.Header.Set("Authorization", fmt.Sprintf("Bearer %s", os.Getenv("SLACK_API_TOKEN")))
client := &http.Client{} response, err := client.Do(request) // HTTPリクエストを送信する. defer response.Body.Close() // deferで宣言しておき,HTTP通信を必ず終了できるようにする. return nil } ・クライアントを起動し,リクエストを送信. ・defer宣言された関数は,たとえ処理が停止しても最後に必ず実行される.
おまけ:例外処理 json, err := json.Marshal(...) if err != nil {
return err } request, err := http.NewRequest(...) if err != nil { return err } ・Goの思想では例外処理は無駄なものとされ,try-catchが無い. ・多くの関数は二つ目の返却値にエラーを返すため,毎回検証するしかない.
最後に Gopherくん 超かわいい!!! by Takuya Ueda (https://twitter.com/tenntenn) The Gopher character
is based on the Go mascot designed by Renée French.