Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Go Code Generation at newmo / 2024-08-27 #newmo...
Search
genkey6
August 27, 2024
Programming
0
620
Go Code Generation at newmo / 2024-08-27 #newmo_layerx_go
newmo × LayerX "Go"同 勉強会
https://layerx.connpass.com/event/323385/
genkey6
August 27, 2024
Tweet
Share
Other Decks in Programming
See All in Programming
What is TDD?
urakawa_jinsei
1
220
GrafanaのHTTP API を眺めてみよう
rinchoku
0
140
Kubernetes上でOracle_Databaseの運用を楽にするOraOperatorの紹介
nnaka2992
0
150
Pydantic x Database API:turu-pyの開発
yassun7010
1
700
DjangoNinjaで高速なAPI開発を実現する
masaya00
0
520
MLOps in Mercari Group’s Trust and Safety ML Team
cjhj
1
120
CSC509 Lecture 02
javiergs
PRO
0
160
5年分のツケを一気に払った話
soogie
3
1.4k
複数プロダクトの技術改善・クラウド移行に向き合うチームのフレキシブルなペア・モブプログラミングの実践 / Flexible Pair Programming And Mob Programming
honyanya
0
230
コードレビューと私の過去と未来
jxmtst
0
280
App Router 悲喜交々
quramy
7
380
自分だけの世界を創るクリエイティブコーディング / Creative Coding: Creating Your Own World
chobishiba
2
1.7k
Featured
See All Featured
WebSockets: Embracing the real-time Web
robhawkes
59
7.3k
For a Future-Friendly Web
brad_frost
174
9.3k
What the flash - Photography Introduction
edds
67
11k
How To Stay Up To Date on Web Technology
chriscoyier
787
250k
Fantastic passwords and where to find them - at NoRuKo
philnash
50
2.8k
Fashionably flexible responsive web design (full day workshop)
malarkey
404
65k
Keith and Marios Guide to Fast Websites
keithpitt
408
22k
Debugging Ruby Performance
tmm1
73
12k
Learning to Love Humans: Emotional Interface Design
aarron
272
40k
Fontdeck: Realign not Redesign
paulrobertlloyd
81
5.2k
Visualizing Your Data: Incorporating Mongo into Loggly Infrastructure
mongodb
41
9.2k
Building Your Own Lightsaber
phodgson
102
6k
Transcript
genkey6 @ newmo × LayerX "Go" 同 勉強会 / 2024-08-27
Go Code Generation at newmo
自己紹介 • 新卒からスタートアップ2社を経て、2024年7月に newmoに入社 • バックエンドがメインのソフトウェアエンジニアとして運 行管理サービスの開発に携わっている • 鳥が好き 🐦
genkey6 2 Gen Shu
本日お話しすること • newmo では開発時にスキーマからコードを自動生成する schema first な思想を中心 に据えている • 主にバックエンドのレイヤーで行っている
Go のコード生成の具体的な方法やそれぞれ の要素技術で取り入れている工夫について、実際のコード例を交えつつ紹介する ◦ GraphQL やデータベース周りの話が多め ◦ gRPC にも少し触れる 3
GraphQL のコード生成|gqlgen を使った開発 4 schema first なアプローチで GraphQL server を開発
GraphQL のコード生成|field resolver @goField directive をつけて field resolver として切り出す
• 取得にコストがかかるフィールドは オーバーフェッチを防ぐために field resolver として定義 • gqlgen 的には config ファイルで指 定する方法と schema で指定する方 法が存在する • 可能な限り schema から情報を読み 取れるようにしたいという理由から、 後者を採用 5
GraphQL のコード生成|custom scalar • 以下の custom scalar が存在 ◦ Timestamp
◦ Date ◦ YearMonth ◦ UUID ◦ Base64String schema 上で頻出する型を custom scalar として定義 6
GraphQL のコード生成|custom directive validation 用に custom directive を定義 • 以下の
directive が存在 ◦ @validateInt ◦ @validateFloat ◦ @validateBoolean ◦ @validateString ◦ @validateArray 7
GraphQL のコード生成|custom directive validation 用に custom directive を定義 • model
の生成時に Go の struct tags に validation の情報が付与される 8
GraphQL のコード生成|custom plugin • template を修正して Go の struct の
interface を満たすような UnimplementedHogeResolver を生成することで schema のみの変更をマージでき るようにしている gqlgen を fork して一部 plugin に手を加えている 9
GraphQL のコード生成|custom plugin validation struct tags の付与も plugin の改造で実現
10 before after
GraphQL のコード生成|custom plugin API テスト用の GraphQL operation file を自動生成する自作 plugin
• Yamashou/gqlgenc を使って GraphQL operation file から GraphQL Client を生成している • 手書きしていることでフィールドの指定漏れが起きるの を防ぎたい 11
GraphQL のコード生成|custom plugin • gqlgen のコード生成時に作られる AST を活用して簡単に実装できた 12 API
テスト用の GraphQL operation file を自動生成する自作 plugin
GraphQL のコード生成|(番外編)fake server 13 directive で指定した値をクライアント向けに fake として返す仕組み
GraphQL のコード生成|(番外編)fake server • schema からレスポンスの fake を生成する 際に @example
directive で指定した値をデ フォルト値として利用 • 詳細は newmo-oss/graphql-fake-server に 14 directive で指定した値をクライアント向けに fake として返す仕組み
gRPC のコード生成|field behavior & protovalidate proto で記載した field behavior を
protovalidate を用いて検証 • 以下の behavior が存在 ◦ OPTIONAL ◦ REQUIRED ◦ OUTPUT_ONLY ◦ INPUT_ONLY ◦ MUTABLE ◦ IMMUTABLE ◦ IDENTIFIER ◦ PARENT_IDENTIFIER 15
gRPC のコード生成|field behavior & protovalidate proto で記載した field behavior を
protovalidate を用いて検証 • gRPC の interceptor と して実装されている 16
gRPC のコード生成|protoc-gen-go-grpc-newmo モジュラーモノリスならではのボイラープレートコードを自動生成する plugin • component 間の通信に 必要な環境変数の設定 に関する
Go の実装を自 動生成する 17
データベースのコード生成|xo を使った開発 SQL を書いて xo で Go の struct &
レコード操作のための関数を生成 18
データベースのコード生成|xo を使った開発 定義した index に応じた関数が生成される • PRIMARY KEY による
WHERE 句を指定するための 関数 19
データベースのコード生成|xo custom template index を指定するフィールドの型によって生成されるメソッドが変わる • index に time,
date 型のカラムが含まれ る場合は、時刻、日付のレンジで WHERE 句を指定できるような関数が生 成される • この関数を呼び出すことでページングの実 装が簡単にできる 20
データベースのコード生成|xo custom template index を指定するフィールドの型によって生成されるメソッドが変わる • レンジで検索する際に指定できる条 件はこんな感じ 21
データベースのコード生成|xo custom template 独自のメソッドの生成は xo の template を改造することで実現 22
データベースのコード生成|xo custom template 生成される Go の struct の型を調整する目的でも template を改造
• date 型のフィールドは Go の struct でも Date 型として生成さ れて欲しい • template に手を入れる前は BirthDate フィールドが time.Time 型で生成されていた → 改造後は Date 型で生成され るように 23
データベースのコード生成|xo custom template 生成される Go の struct の型を調整する目的でも template を改造
• PostgreSQL の型から Go の型にマッピングする箇所の実装を fork して date 型に対す る条件分岐を追加 24
データベースのコード生成|xo custom template trace の span を仕込むのも自動化している 25
データベースのコード生成|xo custom query 任意の WHERE 句の指定や JOIN などの複雑な操作が必要な場合は custom query
に対応するモデルが生成される 26
データベースのコード生成|xo の課題 query からのコード生成でいくつかの課題が存在する 27 • 生成される Go の
struct が分かれてしまうので、型変換などの処理を別々に実装す る必要があって扱いづらい • custom query による UPDATE が非対応 • nullable なカラムを取得する custom query を書いた際に、生成される Go の struct 上では常に non null な型になってしまう
データベースのコード生成|sqlc の利用を検討中 まずは query による生成から置き換えていこうとしている 28 • 先ほど挙げた xo
の課題が解決できる ◦ (JOIN をしなければ)生成される Go の struct が分かれない ◦ xo では custom query を使う必要があった UPDATE 文にも対応可能 ◦ nullable なカラムに対するクエリ結果が nullable になる • 他にも xo にはなかった便利な点が存在する ◦ SQL をパースしているので、コード生成の精度が高い ◦ コード生成をスキーマファイルから静的に行える( xo はコード生成前にデータベースにスキー マを反映させる必要がある) ◦ クエリを書く際に query parameter の型を指定しなくても自動で判別してくれる
データベースのコード生成|sqlc の利用を検討中 一方で sqlc にも課題は存在する 29 • パースした情報に index
の情報が存在しないため、xo でやっていたような index に 応じた検索用の関数の柔軟な自動生成ができない
• GraphQL、gRPC、データベースの各レイヤーでコード生成に採用しているツールを紹介し つつ、それぞれのツールに対して行っているカスタマイズや取り入れている工夫について 紹介した • 時間の都合で紹介しきれなかった Tips は他にもあるので、気になる方は懇親会でお話し ましょう &
こういうこともできたりしない?という話をしましょう • コード生成を駆使して開発者体験を突き詰めたいエンジニアはぜひ newmo へ! まとめ 30
“ 移動で地域をカラフルに ” Our Mission