Builder
Separates complex object construction from its representation.
Understanding Builder
The Builder pattern separates the construction of a complex object from its representation, allowing the same construction process to create different configurations. In Go, this is commonly implemented as a fluent API where each method returns the builder pointer (*Builder), enabling method chaining like .Host("api").Port(443).Build(). This approach is especially valuable when a struct has many optional fields — it replaces confusing constructors with many parameters or error-prone struct literal initialization where you might forget required fields.
Key Concepts
- •Fluent interface — each setter method returns
*Builder, enabling readable method chains - •Sensible defaults — the builder constructor sets reasonable default values, so the caller only needs to overrides what matters
- •Immutable result — the
Build()method returns a value type (not a pointer), producing an unchangeable final object - •Validation —
Build()can return an error if required fields are missing or values are invalid
When to Use
- • A struct has more than 4-5 fields with many optional ones
- • You want to enforce a readable, step-by-step construction process
- • You need validation before the object is created
- • Different configurations of the same type are common (e.g. test vs prod)
- • The struct has only 2-3 fields — a simple constructor or struct literal is clearer
- • Go's functional options pattern (
WithXxx()variadic functions) is a better fit - • The object is trivial and doesn't need multi-step construction
Structure
How It Works
Start Building
Initialize the builder with default values.
Basic Implementation
A fluent server configuration builder:
Real-World Example: HTTP Request Builder
Building HTTP requests with a clean, chainable API: