本記事はディップ Advent Calendar 2022の5日目の記事です。
言い訳をすると12月頭から体調を崩してしまい、寝込んでいました。
---言い訳終了---
とあるAPIを叩くためのクライアントライブラリを作成していたところ、APIを受ける側がヘッダーに特定のデータを要求している仕様となっていました。
Goのnet/http
パッケージを利用した実装ではたいてい下記のような書き方になると思います。
func ApiCall() {
req, err := http.NewRequest("GET", "https://example.com", strings.NewReader(""))
if err != nil {
//なんらかのエラー処理
}
req.Header.Set("New-RequestHeader", "header-data")
//ここでdebug printします。
fmt.Printf("%v \n", req.Header)
c := hrrp.DefaultClient
res, err := c.Do(req)
if err != nil {
//何らかのエラー処理
}
defer res.Body.Close()
//後続の処理とか
}
debug printの結果
map[New-Requestheader:[header-data]]
httpの仕様では、ヘッダーの大文字小文字は区別しようようですが、前述のAPIでは厳密にヘッダーKeyの大文字小文字を区別するような仕様となっておりNew-RequestHeader
というkeyでないとエラーになるようなものでした。
Goのreq.Header.Set
やreq.Header.Add
は下記関数を利用し、データをセットしているようで、ハイフン直後以外のデータはすべて小文字に変換されてしまうという仕様です。
https://pkg.go.dev/net/textproto#CanonicalMIMEHeaderKey
ですので、↑のSampleでは、Request時にヘッダーがNew-Requestheader
となってしまい、APIサーバからRequest不正のエラーが返ってきてしまう状況でした。
解消方法
解消方法を探していたところ、そもそもreq.Header
はmap[string][]string
型のため、直接データを入れてしまう方法というところに行き着きました。
情報ソースは下記ブログです。
※この記事とまんま同じ事が書いてあるような・・・
https://dhdersch.github.io/golang/2016/08/11/golang-case-sensitive-http-headers.html
解消版のSample sourceは下記となります。
func ApiCall() {
req, err := http.NewRequest("GET", "https://example.com", strings.NewReader(""))
if err != nil {
//なんらかのエラー処理
}
req.Header["New-RequestHeader"] = []string{"header-data"}
//ここでdebug printします。
fmt.Printf("%v \n", req.Header)
c := hrrp.DefaultClient
res, err := c.Do(req)
if err != nil {
//何らかのエラー処理
}
defer res.Body.Close()
//後続の処理とか
}
debug printの結果
map[New-RequestHeader:[header-data]]
これは詰んだのでは・・・?と思ったのですが、意外と簡単な解決方法がありました。
雑な記事となってしまいましたが、皆さんのお役に立てればと思います。
以上