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
2019-13 実践 Go 言語/2019-13 golang
Search
Cybozu
PRO
July 04, 2019
Programming
6
160k
2019-13 実践 Go 言語/2019-13 golang
Cybozu
PRO
July 04, 2019
Tweet
Share
More Decks by Cybozu
See All by Cybozu
AIツール開発ワークショップ(Dify)【サイボウズ新人研修2025】
cybozuinsideout
PRO
7
7k
モバイル【サイボウズ新人研修2025】
cybozuinsideout
PRO
3
2k
Git/GitHub を使う上で知っておくと嬉しいかも Tips【サイボウズ新人研修2025】
cybozuinsideout
PRO
3
3.2k
GitHub Copilot活用【サイボウズ新人研修2025】
cybozuinsideout
PRO
6
6.4k
ソフトウェアライセンス【サイボウズ新人研修2025】
cybozuinsideout
PRO
7
5.6k
エンジニアのためのアウトプット講座 〜知識をシェアするはじめの一歩〜【サイボウズ新人研修2025】
cybozuinsideout
PRO
4
1.8k
Docker入門【サイボウズ新人研修2025】
cybozuinsideout
PRO
3
2.5k
セキュリティ【サイボウズ新人研修2025】
cybozuinsideout
PRO
1
1.7k
TLS 1.3をざっと理解する【サイボウズ新人研修2025】
cybozuinsideout
PRO
2
900
Other Decks in Programming
See All in Programming
A full stack side project webapp all in Kotlin (KotlinConf 2025)
dankim
0
120
Code as Context 〜 1にコードで 2にリンタ 34がなくて 5にルール? 〜
yodakeisuke
0
130
20250704_教育事業におけるアジャイルなデータ基盤構築
hanon52_
5
780
NPOでのDevinの活用
codeforeveryone
0
830
AIともっと楽するE2Eテスト
myohei
6
2.6k
Deep Dive into ~/.claude/projects
hiragram
14
2.5k
たった 1 枚の PHP ファイルで実装する MCP サーバ / MCP Server with Vanilla PHP
okashoi
1
250
Hypervel - A Coroutine Framework for Laravel Artisans
albertcht
1
120
AI コーディングエージェントの時代へ:JetBrains が描く開発の未来
masaruhr
1
140
Team operations that are not burdened by SRE
kazatohiei
1
310
ニーリーにおけるプロダクトエンジニア
nealle
0
830
イベントストーミング図からコードへの変換手順 / Procedure for Converting Event Storming Diagrams to Code
nrslib
2
800
Featured
See All Featured
The Invisible Side of Design
smashingmag
301
51k
Designing Dashboards & Data Visualisations in Web Apps
destraynor
231
53k
Building a Modern Day E-commerce SEO Strategy
aleyda
42
7.4k
Code Review Best Practice
trishagee
69
18k
Building Better People: How to give real-time feedback that sticks.
wjessup
367
19k
Git: the NoSQL Database
bkeepers
PRO
430
65k
Being A Developer After 40
akosma
90
590k
Measuring & Analyzing Core Web Vitals
bluesmoon
7
510
JavaScript: Past, Present, and Future - NDC Porto 2020
reverentgeek
50
5.5k
Building a Scalable Design System with Sketch
lauravandoore
462
33k
Statistics for Hackers
jakevdp
799
220k
Bash Introduction
62gerente
613
210k
Transcript
実践GO言語 2019/07/04 開発本部 深谷敏邦
対象者 ▪ A Tour of Go を読んだ ▪ プロダクションコードは書いたことがない ▪
Go で HTTP client/server を書きたい
アジェンダ ▪ はじめに ▪ 準備 ▪ HTTP Server ▪ HTTP
Client ▪ テスト ▪ json 処理 ▪ エラー処理 ▪ context ▪ go modules ▪ Go 関連のツール
はじめに ▪ はじめに ▪ 準備 ▪ HTTP Server ▪ HTTP
Client ▪ テスト ▪ json 処理 ▪ エラー処理 ▪ context ▪ go modules ▪ Go 関連のツール
はじめに ▪ この講義では簡単なHTTPサーバを例にGoを書く際のエッセンスを学びます ▪ サードパーティライブラリは扱いません ▪ Goは言語機能が少なく、ライブラリよりもイディオムを駆使する言語です – もっと良い書き方、機能がないかと思っても本当にないです –
イディオムを覚えて筋力でプログラムしましょう
準備 ▪ はじめに ▪ 準備 ▪ HTTP Server ▪ HTTP
Client ▪ テスト ▪ json 処理 ▪ エラー処理 ▪ context ▪ go modules ▪ Go 関連のツール
準備 ▪ 講義で使用するコンパイラをダウンロードしてください – go (1.12 くらい)
HTTP Server ▪ はじめに ▪ 準備 ▪ HTTP Server ▪
HTTP Client ▪ テスト ▪ json 処理 ▪ エラー処理 ▪ context ▪ go modules ▪ Go 関連のツール
HTTP Server ▪ Go は HTTP Server に関する機能は標準ライブラリに含んでいる – net/http
▪ 重要な型 – Handler – ResponseWriter – Request – Server
Handler型 ▪ net.httpがユーザーリクエストに反応するためのコールバックインターフェース ▪ ユーザーリクエストはReqeust型に入っている ▪ ReponseWriter型を通してレスポンスする type Handler interface
{ ServeHTTP(ResponseWriter, *Request) }
Request型 ▪ https://golang.org/pkg/net/http/#Request – Method – URL – Header –
Body ▪ この型はClientで使うものと共通 ▪ Bodyがio.ReadCloserインターフェースを満たしているので、ioutil.ReadAllなどで中身 を取り出す ▪ 中身を取り出すのはコードを書く人の責任 ▪ 読んでいる最中にエラーが起きたら、それを処理するのも書く人の責任
ResponseWriter型 ▪ https://golang.org/pkg/net/http/#ResponseWriter – Header().Add()/Header().Set()でヘッダを設定する – WriteHeader でステータスコードを設定する – Writeでレスポンスを返す
▪ この型はio.Write型をみたすのでfmt.Fprintとかが使える ▪ Writeを呼ぶと自動的にWriteHeader(http.StatusOK)がよばれる – エラーステータス返すなら必ずWriteHeaderを先に呼ぶ ▪ エラーを返すならhttp.Errorが便利
ルーティング ▪ リクエストルーティングは簡単なパスベースならhttp.ServeMuxがつかえる – これ自体もHandler ▪ メソッドとか正規表現とか使いたいんですが ▪ 適当なライブラリを探して使う –
決定版はない印象 ▪ 筋力で自前でルーティング – 細かいバリデーションが必要なエンドユーザー相手でなければあり – ルータライブラリが必要になるようなサーバをGoで書きたいですか?
Server型 ▪ https://golang.org/pkg/net/http/#Server ▪ 実際にコネクションを受け付けてHandlerを起動してくれる型 ▪ フィールドはおおよそオプションだが、Timeoutは設定すべき – 後述する Context
を使うとさらに細かいTimeoutが設定可能 ▪ ListenAndServerを呼べばサーバが起動する
HTTP Client ▪ はじめに ▪ 準備 ▪ HTTP Server ▪
HTTP Client ▪ テスト ▪ json 処理 ▪ エラー処理 ▪ context ▪ go modules ▪ Go 関連のツール
HTTP Client ▪ Go は HTTP Client に関する機能は標準ライブラリに含んでいる – net/http
▪ 重要な型 – Client – Request – Response
Client型 ▪ https://golang.org/pkg/net/http/#Client ▪ HTTPリクエストを行うための型 ▪ フィールドはオプションでおおよそ何も指定しなくても良い ▪ http.DefaultClientは使わない方が良い –
設定がグローバル – テストで差し替えれない ▪ 基本的にはDoメソッドだけを使えばよい – Getなどの専用メソッドがあるが、後述するContextが使えない
Request型 ▪ https://golang.org/pkg/net/http/#Request ▪ 見間違いではなくサーバで見たものと同じ ▪ フィールドが多くてびっくりするが、http.NewRequestで生成する
Response型 ▪ https://golang.org/pkg/net/http/#Response ▪ StatusCode にステータスコードが入っている ▪ Body は io.ReadCloser
で ioutil.ReadAll などを使って自分でコンテンツを読む必 要がある ▪ HTTP keep-aliveを利用するにはプログラマが自前でCloseする必要がある – 忘れがちなので注意
テスト ▪ はじめに ▪ 準備 ▪ HTTP Server ▪ HTTP
Client ▪ テスト ▪ json 処理 ▪ エラー処理 ▪ context ▪ go modules ▪ Go 関連のツール
テスト ▪ HTTP関連のテストならhttptest.Serverを使うのがらく – 使い終わったらCloseすること ▪ table driven testが便利
json 処理 ▪ はじめに ▪ 準備 ▪ HTTP Server ▪
HTTP Client ▪ テスト ▪ json 処理 ▪ エラー処理 ▪ context ▪ go modules ▪ Go 関連のツール
JSON処理 ▪ Go は JSONに関する機能は標準ライブラリに含んでいる – encoding/json ▪ 基本型や一部の標準ライブラリに含まれる型を相互変換することができる ▪
自分で定義した型も変換できるがここでは扱わない
Marshal ▪ Goの型からJSONバイト列に変換すること ▪ json.Marshalかjson.Encoderを使う – json.Encoderはio.Writerを使えるのでhttp.ResponseWriterと相性が良い – と思わせておいて、エラーが起きるとWriteHeaderとの順番で難しいことに なるのでjson.Marshalを使うのが良い気がする
Unmarshal ▪ バイト列をGoの型に変換すること ▪ json.Unmarshalかjson.Decoderを使う – json.Decoderがio.Readerを使えるのでhttp.Responseと相性が良い
JSONと型のマッピング ▪ Goのstructはフィールドにタグがかける – どう使うかは言語側は規定していないので好きに使える ▪ jsonパッケージはこの機能を活用する
タグ付け ▪ タグでフィールドにマッピングされるJSONのキーを指定する ▪ マッピングするフィールドは公開する必要がある ▪ 実はタグがなくても公開メンバが自動的にマップされるがわかりにくいのでつ けた方が良い ▪ JSONにキーが現れない場合はそのフィールドは空になる
– キーの存在を判定するならポインタを使うと良い type Foo struct { ID int `json:"id"` Data string `json:"data"` }
エラー処理 ▪ はじめに ▪ 準備 ▪ HTTP Server ▪ HTTP
Client ▪ テスト ▪ json 処理 ▪ エラー処理 ▪ context ▪ go modules ▪ Go 関連のツール
エラー処理 ▪ Goはいわゆる例外を持たない ▪ "エラー"の扱いはコンベンションによる
エラーを返す ▪ エラーを返す関数は戻り値の最後にerror型を書く ▪ 戻り値は次の性質を満たすようにする – もしエラーが起きていないならerror型はnilにする – もしエラーが起きているならerror型はnon-nilである –
もしエラーが起きているならtypeN達は何らかの無効な値である ▪ 大抵ゼロ値が使われる func foo() (int, string, error) { if some error is happened { return 0, "", errors.New("error"); } return 1, "ok", nil }
エラーを判定する ▪ 関数がコンベンションを満たしているなら次のように書ける ▪ エラーを返す関数ではerror型を最初にifでチェック ▪ nilでないなら上位に返す ▪ nilなら処理を継続する func
bar() error { n, s, err := foo() if err != nil { return err } // use n and str return nil }
error型 ▪ 組み込みのインターフェース – error ▪ errors.Newやfmt.Errorfを使って生成する ▪ 特定のエラーであることを伝えたり、付加情報をつけるために自前で定義する 場合もある
プラクティス ▪ Goのerrorはいわゆる例外とは異なりスタックトレースを持たない ▪ そのため雑にerrorを上位に伝播するだけだと何が起こったかわかりにくい – 深いロジックで起こったioエラーがmain関数でログされても意味がない ▪ エラーが起きた時は次のことを行うのが良い –
エラーが起きた箇所でのロギング – エラーをfmt.Errorfなどで付加情報をつけて投げ直す ▪ xerrorsを使うとスタックトレースも手に入る
context ▪ はじめに ▪ 準備 ▪ HTTP Server ▪ HTTP
Client ▪ テスト ▪ json 処理 ▪ エラー処理 ▪ context ▪ go modules ▪ Go 関連のツール
context ▪ 処理を止めるための仕組み – リクエスト単位のkvsとしても使えるがここでは扱わない ▪ 例えば – HTTPリクエストをタイムアウトさせたい –
外部コマンド呼び出しをタイムアウトさせたい – goroutineの実行を途中で止めたい
contextパッケージ ▪ contextは標準のcontextパッケージとコンベンションで実現する ▪ contextを扱う関数は第一引数にcontext型を受け取る – 引数名はctx ▪ context.Doneはchannelで、closeされるとそのcontextが終了したことを示す ▪
context生成関数がCancelFuncを返すなら必ずその関数を呼び出す
HTTPサーバでのContext ▪ HTTPハンドラーのrequest構造体が持つContext()からcontextを取得できる ▪ このcontextはユーザーのコネクションがクローズされると終了する – すなわちcontext.Doneがcloseされる ▪ クライアントのコネクションが閉じた時、ハンドラーの処理を停止できる
HTTPクライアントのContext ▪ http.Clientはcontextのコンベンションを守っていない – contextが後で追加されたため ▪ 引数で直接contextを渡す代わりに、http.Requestに対してcontextを乗せる – WithContext ▪
context.WithTimeoutなどと組み合わせて使う
go modules ▪ はじめに ▪ 準備 ▪ HTTP Server ▪
HTTP Client ▪ テスト ▪ json 処理 ▪ エラー処理 ▪ context ▪ go modules ▪ Go 関連のツール
Go modules ▪ 最近標準で用意されるようになった依存管理方法 – npm, maven, gradle的な ▪ Go
modulesを使うとGOPATHは不要 – GOPATHを使っているとmodulesが誤作動するので注意 ▪ 依存パッケージのバージョンが指定できるのでvendoringが不要になる
使い方 ▪ 初期化 – go.mod が生成される ▪ 依存の追加・削除 – import文から依存がgo.modに追加される
– ベリファイファイルのgo.sumも生成される ▪ ビルド – 自動的に依存がダウンロードされる $ go mod init github.com/foo/bar $ go get github.com/hoge/fuga $ go mod tidy $ go build
Go 関連のツール ▪ はじめに ▪ 準備 ▪ HTTP Server ▪
HTTP Client ▪ テスト ▪ json 処理 ▪ エラー処理 ▪ context ▪ go modules ▪ Go 関連のツール
Go 関連のツール ▪ formatter – go fmt – goimports ▪
不要なimportを消してくれるのでgoimportsを使うのがオススメ ▪ checker/linter – go vet ▪ コーディングミスっぽいものを探してくれる – golint ▪ コードスタイルをチェックしてくれる