build-an-http-client / lesson-32.md
Lesson 32 · Encodings: auth and forms

Encode a set of pairs

A form body is many key-value pairs joined together. Today you encode an ordered set of pairs into the full body string, each side escaped and the pairs joined by ampersands.

The goal

Encode an ordered list of key-value pairs into a form-urlencoded body string.

Start here - the target
TO DO
Scenario: Encoding a full form body
Giventhe ordered pairs (q, "a b") and (lang, "en")
Whenthey are encoded as a form body
Thenthe result is "q=a+b&lang=en" (each key and value form-encoded, joined by "=", pairs joined by "&")
Andthe pairs keep the given order, so the output is deterministic
Background

A form body is a run of key=value pairs joined by &, each key and value individually form-encoded. The pairs (q, "a b") and (lang, "en") become q=a+b&lang=en - the space in the value is a +, the = between key and value and the & between pairs are the structural separators (which is why any literal = or & inside a value gets escaped to %3D or %26).

Keep the pairs in an ordered list, not a map, so the output is deterministic - the same input always produces the same bytes, exactly as you did with sorted headers in chapter two. Deterministic form bodies are what make the request tests exact. This is the encoder; reading a form body back into pairs is the decoder, next, and it doubles as the URL query parser you deferred in chapter one.

Make it work
// for each pair: formEscape(key) + "=" + formEscape(value).
// join the pairs with "&". keep the caller's order (use an
// ordered list, not a map) so the bytes are deterministic.
type Pair struct { Key, Value string }
func encodeForm(pairs []Pair) string { /* join "k=v" with "&" */ }
CheckpointDONE
You can encode an ordered set of pairs into a form body. Commit and stop here.