English rewrite of xb/doc/BUILDER_BEST_PRACTICES.md. It captures conventions field teams use to keep builders predictable and readable.
ListUserRequest).*uint64 or *string distinguishes “unset” from “zero”.Eq.| Tip | Why it helps |
|---|---|
| Group related conditions | Easier to scan, reuse via helper functions |
Use Cond(func(cb *CondBuilder)) |
Better than stacking Or() calls with manual parentheses |
| Keep method ordering consistent | Select → From → Join → Where → Sort → Limit mirrors SQL |
| Avoid side effects inside closures | Builders are pure data; keep IO outside |
func addTenantGuard(b *xb.Builder, tenantID uint64) *xb.Builder {
return b.Eq("tenant_id", tenantID)
}
func addPagination(b *xb.Builder, req *PageRequest) *xb.Builder {
return b.Limit(req.Limit()).Offset(req.Offset())
}
Meta(func(*interceptor.Metadata)) to embed TraceID, UserID, or RequestID.built.Raw() dumps in unit tests for fast regression diagnosis.InRequired, Bool, X, and Sub give you precise control when auto-filtering is not enough.DELETE FROM table accidentally.doc/en/FILTERING.mddoc/en/CUSTOM_INTERFACE.mddoc/en/TESTING_STRATEGY.md