API Design Patterns
Builder API
Configure Then Build
A builder keeps optional configuration separate from the final value that callers actually use.
Program
Play the program to choose a timeout and build a request through chained methods.
builder_request_config.rs
struct Request {
method: &'static str,
path: &'static str,
timeout: u32,
}
struct RequestBuilder {
method: &'static str,
path: &'static str,
timeout: u32,
}
impl RequestBuilder {
fn new(path: &'static str) -> Self {
Self { method: "GET", path, timeout: 10 }
}
fn timeout(mut self, seconds: u32) -> Self {
self.timeout = seconds;
self
}
fn build(self) -> Request {
Request { method: self.method, path: self.path, timeout: self.timeout }
}
}
fn main() {
let timeout = ;
let request = RequestBuilder::new("/v1").timeout(timeout).build();
println!("{} {} timeout={}", request.method, request.path, request.timeout);
}
struct Request {
method: &'static str,
path: &'static str,
timeout: u32,
}
struct RequestBuilder {
method: &'static str,
path: &'static str,
timeout: u32,
}
impl RequestBuilder {
fn new(path: &'static str) -> Self {
Self { method: "GET", path, timeout: 10 }
}
fn timeout(mut self, seconds: u32) -> Self {
self.timeout = seconds;
self
}
fn build(self) -> Request {
Request { method: self.method, path: self.path, timeout: self.timeout }
}
}
fn main() {
let timeout = ;
let request = RequestBuilder::new("/v1").timeout(timeout).build();
println!("{} {} timeout={}", request.method, request.path, request.timeout);
}
struct Request {
method: &'static str,
path: &'static str,
timeout: u32,
}
struct RequestBuilder {
method: &'static str,
path: &'static str,
timeout: u32,
}
impl RequestBuilder {
fn new(path: &'static str) -> Self {
Self { method: "GET", path, timeout: 10 }
}
fn timeout(mut self, seconds: u32) -> Self {
self.timeout = seconds;
self
}
fn build(self) -> Request {
Request { method: self.method, path: self.path, timeout: self.timeout }
}
}
fn main() {
let timeout = ;
let request = RequestBuilder::new("/v1").timeout(timeout).build();
println!("{} {} timeout={}", request.method, request.path, request.timeout);
}
builder
A builder stores configuration while the caller chains methods.
by-value methods
`timeout` takes and returns `self`, which supports method chaining.
final type
`build` creates the finished `Request` value with the selected configuration.