Response Helpers
The contract/response package provides functions for writing HTTP responses with proper content types and status codes. Since Cosmos handlers return error, these functions return error too, letting you chain them in a single return statement.
Serialize any value to JSON:
import "github.com/studiolambda/cosmos/contract/response"
func listUsers(w http.ResponseWriter, r *http.Request) error { users := []User{{Name: "Alice"}, {Name: "Bob"}} return response.JSON(w, http.StatusOK, users)}Sets Content-Type: application/json and uses json.Encoder for streaming serialization.
Serialize to XML:
return response.XML(w, http.StatusOK, catalog)Sets Content-Type: application/xml.
Write an HTML string:
return response.HTML(w, http.StatusOK, "<h1>Hello</h1>")Sets Content-Type: text/html.
HTML Templates
Section titled “HTML Templates”Render a Go html/template:
tmpl := template.Must(template.ParseFiles("page.html"))
func page(w http.ResponseWriter, r *http.Request) error { return response.HTMLTemplate(w, http.StatusOK, *tmpl, data)}Plain Text
Section titled “Plain Text”Write plain text:
return response.String(w, http.StatusOK, "OK")Sets Content-Type: text/plain; charset=utf-8.
Text Templates
Section titled “Text Templates”Render a Go text/template:
tmpl := template.Must(template.New("").Parse("Hello, {{.Name}}!"))
return response.StringTemplate(w, http.StatusOK, *tmpl, data)Raw Bytes
Section titled “Raw Bytes”Write raw bytes without setting a content type:
return response.Raw(w, http.StatusOK, rawData)Binary Data
Section titled “Binary Data”Write binary data with Content-Type: application/octet-stream:
return response.Bytes(w, http.StatusOK, fileContents)Status Only
Section titled “Status Only”Send a status code with no body:
return response.Status(w, http.StatusNoContent)Redirects
Section titled “Redirects”Send an HTTP redirect:
return response.Redirect(w, http.StatusFound, "/dashboard")Common status codes for redirects:
301— Moved Permanently302— Found (temporary)303— See Other (after POST)307— Temporary Redirect (preserves method)308— Permanent Redirect (preserves method)
Streaming
Section titled “Streaming”Stream data to the client in real time using channels:
func streamLogs(w http.ResponseWriter, r *http.Request) error { ch := make(chan []byte)
go func() { defer close(ch) for line := range logSource { ch <- []byte(line + "\n") } }()
return response.Stream(w, r, ch)}Stream sets Cache-Control: no-cache and Connection: keep-alive, then reads from the channel and flushes after each write. It returns when:
- The channel is closed (graceful shutdown, returns
nil). - The request context is canceled (returns the context error).
If the http.ResponseWriter does not support http.Flusher, it returns response.ErrNonFlushableWriter.
Server-Sent Events (SSE)
Section titled “Server-Sent Events (SSE)”For SSE, use the SSE function which adds the Content-Type: text/event-stream header and delegates to Stream:
func events(w http.ResponseWriter, r *http.Request) error { ch := make(chan []byte)
go func() { defer close(ch) for event := range eventSource { data, _ := json.Marshal(event) ch <- append([]byte("data: "), append(data, '\n', '\n')...) } }()
return response.SSE(w, r, ch)}You’re responsible for formatting the SSE data according to the EventSource specification — the function handles the streaming transport.