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
サイボウズ 開発本部採用ピッチ / Cybozu Engineer Recruit
cybozuinsideout
PRO
9
45k
テクニカルライティング
cybozuinsideout
PRO
4
300
サイボウズのアジャイルクオリティ2024
cybozuinsideout
PRO
3
260
モブに早く慣れたい人のためのガイド2024
cybozuinsideout
PRO
3
360
モバイル
cybozuinsideout
PRO
3
180
ソフトウェアライセンス
cybozuinsideout
PRO
4
160
ソフトウェアテスト
cybozuinsideout
PRO
3
260
自動テスト
cybozuinsideout
PRO
3
270
Docker入門2024
cybozuinsideout
PRO
3
450
Other Decks in Programming
See All in Programming
as(型アサーション)を書く前にできること
marokanatani
9
2.6k
Generative AI Use Cases JP (略称:GenU)奮闘記
hideg
1
290
2024/11/8 関西Kaggler会 2024 #3 / Kaggle Kernel で Gemma 2 × vLLM を動かす。
kohecchi
5
910
Streams APIとTCPフロー制御 / Web Streams API and TCP flow control
tasshi
2
350
Laravel や Symfony で手っ取り早く OpenAPI のドキュメントを作成する
azuki
1
110
「今のプロジェクトいろいろ大変なんですよ、app/services とかもあって……」/After Kaigi on Rails 2024 LT Night
junk0612
5
2.1k
Creating a Free Video Ad Network on the Edge
mizoguchicoji
0
120
ピラミッド、アイスクリームコーン、SMURF: 自動テストの最適バランスを求めて / Pyramid Ice-Cream-Cone and SMURF
twada
PRO
10
1.3k
AI時代におけるSRE、 あるいはエンジニアの生存戦略
pyama86
6
1.1k
Less waste, more joy, and a lot more green: How Quarkus makes Java better
hollycummins
0
100
OSSで起業してもうすぐ10年 / Open Source Conference 2024 Shimane
furukawayasuto
0
100
WebフロントエンドにおけるGraphQL(あるいはバックエンドのAPI)との向き合い方 / #241106_plk_frontend
izumin5210
4
1.4k
Featured
See All Featured
Fantastic passwords and where to find them - at NoRuKo
philnash
50
2.9k
The Invisible Side of Design
smashingmag
298
50k
Why You Should Never Use an ORM
jnunemaker
PRO
54
9.1k
Principles of Awesome APIs and How to Build Them.
keavy
126
17k
Visualizing Your Data: Incorporating Mongo into Loggly Infrastructure
mongodb
42
9.2k
Product Roadmaps are Hard
iamctodd
PRO
49
11k
Ruby is Unlike a Banana
tanoku
97
11k
Git: the NoSQL Database
bkeepers
PRO
427
64k
Intergalactic Javascript Robots from Outer Space
tanoku
269
27k
A better future with KSS
kneath
238
17k
Designing Dashboards & Data Visualisations in Web Apps
destraynor
229
52k
Become a Pro
speakerdeck
PRO
25
5k
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 ▪ コードスタイルをチェックしてくれる