---
title: A Trick for Designing Friendly APIs in Go
theme: default
layout: center
class: text-center
fonts:
sans: "CaskaydiaCove Nerd Font Mono"
---
# A Trick for Designing
Friendly APIs in Go
---
layout: center
---
# The Optional Configuration Problem
```go
// No defaults?
// What is sensible?
// What does 'true' do?
// What is '30'?
srv := NewServer("localhost", 8080, 30, true)
```
---
layout: center
---
# "We need to add a TLS parameter."
```go
func NewServer(host string, port int, timeout int) *Server {
// ...
}
```
---
layout: center
---
# "Just use a struct"
```go
srv := NewServer(Config{
Host: "localhost",
Port: 0,
})
```
---
layout: center
class: text-center
---
# "Nah bro, use functional options."
---
layout: center
---
# 1. Define the option
```go
type Server struct {
host string
port int
}
// Option is a function that modifies the Server
type Option func(*Server)
```
---
layout: center
---
# 2. Create closures
```go
// WithPort captures the 'port' value
func WithPort(port int) Option {
// It returns a closure
return func(s *Server) {
s.port = port
}
}
func WithHost(h string) Option {
return func(s *Server) {
s.host = h
}
}
```
---
layout: center
class: text-center
---
# 3. Get variadic