掲題のとおりCloud Runで以下のエラーが発生
POST 415 324B 389ms Google-Cloud-Scheduler
echoはGoのwebフレームワーク
path parameterを使いたくて利用
echoのエラーログは以下
error: code=415, message=Unsupported Media Type
Unsupported Media Type
とのことなのでContent-Typeが原因っぽい
結論
Cloud scheduler からくるリクエストヘッダはGUIから設定するとContent-Type
が設定されず、
echo.Context.Bind
を使ったリクエストのパースをすると上記エラーが発生する
事象発生環境
- go 1.14
- echo 3.3.10
echo リクエストパース部分
Content-Type: application/json
を想定していたのでリクエストボディのjsonを読み込んでstructにする部分を下記のように実装してCloud Runにデプロイ
Message struct {
RoomNames []string `json:"RoomNames"`
}
func Handler(c echo.Context) error {
var m Message
m := new(Message)
if err := c.Bind(m); err != nil {
return err
}
...
}
下記のcurlでは成功
curl -H "Content-Type: application/json" -d '{"RoomNames":["living", "study"]}'
Cloud Schedulerの設定
HTTPメソッドをPOSTで下記Bodyを設定
{"RoomNames":["living", "study"]}
上記415エラーが発生
解決
gcloud scheduler jobs update http
のオプションで --update-headers=Content-Type=application/json
をつけてリクエストヘッダを変更する
もしくは以下
echo リクエストパース部分を下記の通り変更したところCloud Schedulerからリクエストしても成功するようになった
func Handler(c echo.Context) error {
var m Message
b, err := ioutil.ReadAll(c.Request().Body)
defer c.Request().Body.Close()
if err != nil {
log.Printf("ioutil.ReadAll: %v", err)
return echo.ErrBadRequest
}
if err := json.Unmarshal(b, &m); err != nil {
log.Printf("json.Unmarshal: %v", err)
return echo.ErrBadRequest
}
}
おわり
Cloud Schedulerの設定GUIにはヘッダを設定する場所がなく、勝手にContent-Type
が付いてるもんだと思ってた
単なる思い込み