01
Networking and Data Formats
Building request handlers and the middleware pattern in the standard library, the client side's timeout and body-closing responsibility, carrying field names across with struct tags, templates producing only text, contract-based communication with a schema shared by both sides, and the single piece of information framing carries in a long-lived connection.
- 01 HTTP Server The course's opening lesson. That none of a request's path, header, and body carry type information is measured with `net/http/httptest`, without opening a real port; the middleware pattern runs as a three-ring chain in which one handler wraps another. The limiting measure: the content type header is a hint, not a type — a wrong hint produces no error on the server side, the error only surfaces on the side that tries to resolve the body against that hint.
- 02 HTTP Client The previous lesson measured the boundary from the receiving side; this lesson measures the same boundary from the sending side. A timeout is built not with a duration but with an already-canceled context. Whether a connection gets reused depends on whether the response body is closed: once the body is read and closed, the next request uses the same connection; if it is not closed, the next request does not. The limiting measure: the response body is a reader, not a value — once read, a second read returns empty.
- 03 JSON Serialization The course's binding number is produced here: of the thirteen boundary crossings, type information is preserved in 1, rebuilt in 5, lost in 7. The schema that carries a struct's field names across is the struct tag; the same byte sequence decoded into an untyped container turns an integer into `float64`, a field with no counterpart on the receiver drops silently, and no error surfaces. The limiting measure: appearing to be rebuilt does not mean it was rebuilt correctly.
- 04 Templates The same template text, run with two different Go types (an integer, a decimal number), produces byte-for-byte identical output; the source's type information is lost entirely at the output. A field name appears in the output only if it was written into the template's own text — it does not come from the type system. Text and HTML templates turn the same data into different byte sequences with respect to escaping. The limiting measure: a template looks up field names at run time, a nonexistent field only becomes known at execution, not at compile time, and the error is born in the middle of the output.
- 05 Contract-Based Service Communication The source of two independent processes is generated with text/template from the same shared schema (a list of field names, field types, JSON tags) and compiled and run separately. While the schema is shared, all three fields preserve their type — the single line, among the course's thirteen boundary crossings, that falls into the preserved class. Once the schema diverges (if the receiving side's generator is out of date), the crossing breaks silently: two of the three fields preserve their type, one is lost without ever producing an error.
- 06 Real-Time Communication A long-lived connection is modeled, without opening a real port, with a byte buffer implementing io.Reader and io.Writer. The server pushes three messages one after another, without waiting for a request between them. In an unframed stream, the three pushes merge into a single byte sequence and fixed-size reads cannot correctly separate any message (0/3); in a stream framed with a length prefix, all three parse back correctly (3/3). The limiting measure: framing gives where a message ends, not the type of the value inside it.