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
GopherCon 2019 Report
Search
upamune / Yu SERIZAWA
August 20, 2019
Programming
0
2.1k
GopherCon 2019 Report
mercari.go #10で発表したGopherCon 2019 Reportの発表資料です.
upamune / Yu SERIZAWA
August 20, 2019
Tweet
Share
More Decks by upamune / Yu SERIZAWA
See All by upamune / Yu SERIZAWA
来週から実践できる! LayerXのバクラク事業部で行われている Go 関連の読書会のご紹介 / Bakuraku Go Reading Group
upamune
7
560
冗長なエラーログを削減し、スタックトレースを手に入れる / Reducing Verbose Error Logs and Obtaining Stack Traces
upamune
1
1.8k
バクラク事業部でのGoのユースケースとチームを超えたナレッジ共有 | hatena.go
upamune
9
3.4k
未卒 🔜 新卒 / Misotsu soon New Grads
upamune
2
670
Other Decks in Programming
See All in Programming
Click-free releases & the making of a CLI app
oheyadam
2
120
Jakarta EE meets AI
ivargrimstad
0
220
役立つログに取り組もう
irof
28
9.6k
Arm移行タイムアタック
qnighy
0
330
Amazon Bedrock Agentsを用いてアプリ開発してみた!
har1101
0
340
PHP でアセンブリ言語のように書く技術
memory1994
PRO
1
170
2024/11/8 関西Kaggler会 2024 #3 / Kaggle Kernel で Gemma 2 × vLLM を動かす。
kohecchi
5
930
flutterkaigi_2024.pdf
kyoheig3
0
150
とにかくAWS GameDay!AWSは世界の共通言語! / Anyway, AWS GameDay! AWS is the world's lingua franca!
seike460
PRO
1
900
Better Code Design in PHP
afilina
PRO
0
130
TypeScript Graph でコードレビューの心理的障壁を乗り越える
ysk8hori
2
1.1k
[Do iOS '24] Ship your app on a Friday...and enjoy your weekend!
polpielladev
0
110
Featured
See All Featured
Designing on Purpose - Digital PM Summit 2013
jponch
115
7k
How STYLIGHT went responsive
nonsquared
95
5.2k
Why You Should Never Use an ORM
jnunemaker
PRO
54
9.1k
Design and Strategy: How to Deal with People Who Don’t "Get" Design
morganepeng
126
18k
A better future with KSS
kneath
238
17k
Sharpening the Axe: The Primacy of Toolmaking
bcantrill
38
1.8k
What’s in a name? Adding method to the madness
productmarketing
PRO
22
3.1k
The Myth of the Modular Monolith - Day 2 Keynote - Rails World 2024
eileencodes
16
2.1k
Practical Orchestrator
shlominoach
186
10k
The Illustrated Children's Guide to Kubernetes
chrisshort
48
48k
Building Flexible Design Systems
yeseniaperezcruz
327
38k
Learning to Love Humans: Emotional Interface Design
aarron
273
40k
Transcript
GopherCon 2019 Report mercari.go #10 @upamune
About Me @upamune (うぱみゅん) Merpay, Inc. / CodePayment Team Backend
Engineer
発表するトーク
How I Write HTTP Web Services After Eight Years Mat
Ryer 出典: https://medium.com/@matryer
Who is Mat Ryer?
Mat Ryer Blog medium.com/@matryer Podcast Go Time Books Go ⾔語による
Web アプリケーション開発 Go Programming Blueprints OSS BitBar Testify Gopherize.me etc...
出典: GoTime https://cdn.changelog.com/uploads/covers/go-time-medium.png Go⾔語によるWebアプリケーション開発 https://www.amazon.co.jp/dp/4873117526 Go Programming Blueprints https://www.amazon.co.jp/dp/B01GQCQ8OW
トーク概要
トーク概要 Go で HTTP service をどう書いているか HTTP service を書く時に重要な要素を紹介 いくつかのパターンを紹介
重要な要素
重要な要素 Maintainability Glaceability Code should be boring Self Similar code
Maintainability 最初から Maintainability を考慮して書く 考慮しないと、メンテナンスコストがツールを作る時よりも⼤きくなる可能性
Glaceability 視認性 コードを読んでどれくらい早くコードを理解できるか コードだけではなく、プロジェクト構造なども含まれる 関数、名前空間、変数名、コードの構造、etc...
Code should be boring 他の⼈が理解できるように書く 経験のほとんどない⼈がコードを利⽤する可能性があることを理解するのが重要
Self Similar code コードベース内の他のコードに似たコードがあると、 他の⼈がコードに親しみやすくなる
Design Patterns/Decisions
全部紹介しきれないのでいくつかピックアップ
Creating a server struct & a constructor for the server
type server struct { db *someDatabase router *someRouter email EmailSender } func newServer() *server { s := &server{} s.routes() return s } グローバル変数は利⽤しない それを避けるために server 構造体が持つ newServer では依存をセットアップしない テストのため 多くなければ引数でとっても良い ルーティングだけセットアップする
Routing // routes.go func (s *server) routes() { s.router.Get("/api/", s.handleAPI())
s.router.Get("/about", s.handleAbout()) s.router.Get("/", s.handleIndex()) } ⼀箇所でルーティングを管理する 視認性 ⤴ URL からどのハンドラーを利⽤しているか容易に特定できる
Dealing with data // Respond helper func (s *server) respond(w
http.ResponseWriter, r *http.Request, data interface{}, status int) { w.WriteHeader(status) if data != nil { err := json.NewEncoder(w).Encode(data) // TODO: handle error } } // Decoding helper func (s *server) decode(w http.ResponseWriter, r *http.Request, v interface{}) error { return json.NewDecoder(r.Body).Decode(v) } 抽象化する 後から Accept ヘッダーや Content-Type ヘッダーに対応することが容易に ヘルパーは http.ResponseWriter と *http.Request を引数で受け取る
Request and response func (s *server) handleGreet() http.HanlderFunc { type
request struct { Name string `json:"name"` } type response struct { Greeting string `json:"greeting"` } return func(w http.ResponseWriter, r *http.Request) { // do something... } } Handler に関連する Request/Response が⾒つけやすい 関数の中で定義しているので request , response という短い構造体名にできる
Request and response func TestGreet(t *testing.T) { is := is.New(t)
p := struct{ Name string `json:"name"` }{ Name: "Yu SERIZAWA", } // ... test code } テストの際は request 構造体を参照できないので、リクエストの struct を定義する Name フィールドだけこのテストでは関係するとわかる
Lazy setup func (s *server) handleTemplate(file string...) http.HandleFunc { var
( init sync.Once tpl *template.Template tplerr error ) return func(w http.ResposeWriter, r *http.Request) { init.Do(func() { tpl, tplerr = template.ParseFiles(files...) }) if tplerr != nil { // return error } // use template } } 重い処理を呼ばれるまで sync.Once で遅らせる GAE を利⽤する場合などで起動時間を速くしたい場合に有効
残りは元スライド、ライブブログで
matryer/is is ... ? I call it “Testify off steroids”
:) https://gophers.slack.com/archives/C0528UE9X/p1564348834304100?thread_ts=1564339225.294700&cid=C0528UE9X
matryer/is func Test(t *testing.T) { is := is.New(t) signedin, err
:= isSignedIn(ctx) is.NoErr(err) // isSignedIn error is.Equal(signedin, true) // must be signed in body := readBody(r) is.True(strings.Contains(body, "Hi there")) } https://github.com/matryer/is#usage
トークの感想 だいたい似たよう感じに作っているので安⼼できた 業務で HTTP sevice を作ることはほとんどないが、 HTTP service 以外を書く時でも 参考にできることがあった
最初に挙げていた重要な要素など testify を置き換えたい
参考リンク Slide https://gophers.slack.com/archives/C0528UE9X/p1564339225294700 このレスに is の説明もあります 元になったブログ記事 https://medium.com/statuscode/how-i-write-go-http-services-after-seven- years-37c208122831 LiveBlog
https://about.sourcegraph.com/go/gophercon-2019-how-i-write-http-web- services-after-eight-years