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
2019-13 実践 Go 言語/2019-13 golang
Search
Cybozu
PRO
July 04, 2019
Programming
170k
6
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
2019-13 実践 Go 言語/2019-13 golang
Cybozu
PRO
July 04, 2019
More Decks by Cybozu
See All by Cybozu
サイボウズ 開発本部採用ピッチ / Cybozu Engineer Recruit
cybozuinsideout
PRO
12
94k
新卒1年目QAが リリース基準の"なぜ"をたどってみた
cybozuinsideout
PRO
1
960
kintone リサーチ副部/UXリサーチャー 業務紹介
cybozuinsideout
PRO
0
210
私たちが『JaSST協賛』から『外部コネクト』チームになった理由
cybozuinsideout
PRO
0
620
LLMでもいつものテスト技術〜意外と半分はこれまでのテストでした〜
cybozuinsideout
PRO
1
1.2k
kintone開発のプラットフォームエンジニアの紹介
cybozuinsideout
PRO
1
1.8k
LLMアプリの品質保証
cybozuinsideout
PRO
1
910
技術広報チームに丸投げしない!「一緒につくる」スポンサー活動
cybozuinsideout
PRO
0
320
テクニカルライター (グループウェア) について
cybozuinsideout
PRO
0
320
Other Decks in Programming
See All in Programming
Zero-Tap Sign-In対応、結局何をすればいいの?
mitohato14
0
570
Coding with AI: How to trust the storyteller (AWS Community Day Adria, Ljubljana 2026)
slobodan
0
110
S3 TablesのIcebergデータに、AIエージェントからアクセスしてみた / 20261016developersio2026joetsu-accessing-iceberg-in-s3tables-via-agent
kasacchiful
PRO
0
200
[2026-10-09]一枚の布で作らなくてもいい。 信頼性は「パッチワーク」で紡がれる~既存の運用と新しい可能性をつなぎ合わせてきたCREの話~
tosite
0
110
見えないものを探る要求要件定義に必要な基本的思考 / invisible-requirement-thinking
minodriven
15
8.7k
GraphQL の onError と Nullability のこれから
quramy
0
180
[Dev Group Paris Octobre 26] Agentforce, SIforce, Claudeforce, Slackbot… on s'y retrouve ?
nabondance
0
120
APNsからLive Activityを開始する話
yumnumm
0
170
contenteditable と日本語入力に向き合う
colorful12
0
210
あなたの await、OS まで届いてる? strace で覗く JavaScript の非同期
hasutosasaki
1
1.3k
[JA] Domain Modeling with Vanilla Rails: 「操作」から再考するRailsの設計論
yasaichi
4
880
【加筆修正版】Laravel のアプリケーションをどこにデプロイするか #phpcon_ehime
akase244
0
160
Featured
See All Featured
Git: the NoSQL Database
bkeepers
PRO
433
67k
Google's AI Overviews - The New Search
badams
0
1.6k
StorybookのUI Testing Handbookを読んだ
zakiyama
31
7k
Efficient Content Optimization with Google Search Console & Apps Script
katarinadahlin
PRO
1
940
Code Review Best Practice
trishagee
74
20k
Done Done
chrislema
187
17k
HU Berlin: Industrial-Strength Natural Language Processing with spaCy and Prodigy
inesmontani
PRO
0
760
[RailsConf 2023] Rails as a piece of cake
palkan
59
7.1k
JavaScript: Past, Present, and Future - NDC Porto 2020
reverentgeek
52
6.1k
VelocityConf: Rendering Performance Case Studies
addyosmani
331
25k
Fireside Chat
paigeccino
43
4.1k
Creating an realtime collaboration tool: Agile Flush - .NET Oxford
marcduiker
35
2.6k
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 ▪ コードスタイルをチェックしてくれる