Goアドベントカレンダーの欠番があったので穴埋めで書きました。
ちょっとウェブアプリケーション開発をがんばった経験がかなりある人であったり、Real World HTTPの熱心な読者であったり、Real World HTTPの熱心な読者の人であれば、フロントエンドからサーバーにデータを送信する手段が何種類もあることはご存知でしょう。
- クエリー(URL)
- ヘッダーフィールド
- ボディ
本ではステータスコードも入れて4兄弟のように説明していたけど、サーバー→クライアント方向なのでここでは触れないでおきます。このうちヘッダーはメタデータなのでここで扱うのは2つですが、ボディを使うのは主にフォームのポスト(x-www-form-urlencodedとmultipart/form-data)と最近はJSONですね。
- クエリー(URL)
- ボディ
- x-www-form-urlencoded
- multipart/form-data
- JSON
GoのAPIはJSON以外の3つが微妙に透過的に扱えるけど微妙にクセがある挙動なのでまとめておきます。
Goでリクエストからデータにアクセスするメソッドが3つあります。
FormValue()
PostFormValue()
FormFile()
これらのメソッドはParseForm()
やParseMultipartForm(maxMemory int64)
の結果が入るForm
はPostForm
にアクセスしますが、必要に応じてこれらのパースのメソッドも呼んでくれます。なお、マルチパートのmaxMemoryはデフォルトで32MBなのでそれ以上のファイルを扱いたい場合は自前で呼ぶ必要があります。
FormValue() |
PostFormValue() |
FormFile() |
|
---|---|---|---|
クエリー | ○ | ||
x-www-form-urlencoded | ○(優先) | ○ | |
multipart/form-data(ファイル以外) | ○ | ||
multipart/form-data(ファイル) | ○ |
同じキーのものがクエリーとx-www-form-urlencodedの両方にあるとx-www-form-urlencodedの方が優先される点は要注意ですが、まあそんなAPI設計にはしないと思うので(swagger上もやっかい)、まあ無視してもいいかと思います。
自動生成でがつっと生成する時は、このあたりのAPIを自分で呼ぶことはないと思いますが、これの何が便利かというと、テストで便利ですよね。次のようなリクエストはGETだけどボディがx-www-form-urlencodedでエンコードされたリクエストという変則的なリクエストになりますが、クエリーで渡すのと同じようにFormValue()
で値が取れます。
$ curl -X GET -d "searchparam=small animal" http://localhost:8000/search
自分でエンコードとか頑張らなくてもcurlで気軽にリクエストが投げられて便利ですね。