Buffalo — API Surface#
API types#
- Library (primary) — Buffalo is consumed as a Go package; users write their own
main.go - Plugin CLI (secondary) — external binaries integrate via a JSON IPC protocol using Cobra commands
There is no REST API, gRPC API, or standalone CLI binary shipped by this repo. The buffalo CLI scaffolding tool is a separate repository.
Library API#
Root package (github.com/gobuffalo/buffalo)#
Entry points#
| Function / Type | Signature | Purpose |
|---|---|---|
New | func New(opts Options) *App | Construct and configure a Buffalo application |
NewOptions | func NewOptions() Options | Return an Options struct with sensible defaults |
App — routing methods#
All HTTP methods return *RouteInfo which can be further configured (name, resource name, etc.):
| Method | Signature |
|---|---|
GET | (a *App) GET(p string, h Handler) *RouteInfo |
POST | (a *App) POST(p string, h Handler) *RouteInfo |
PUT | (a *App) PUT(p string, h Handler) *RouteInfo |
DELETE | (a *App) DELETE(p string, h Handler) *RouteInfo |
PATCH | (a *App) PATCH(p string, h Handler) *RouteInfo |
HEAD | (a *App) HEAD(p string, h Handler) *RouteInfo |
OPTIONS | (a *App) OPTIONS(p string, h Handler) *RouteInfo |
ANY | (a *App) ANY(p string, h Handler) — registers all 7 methods |
Redirect | (a *App) Redirect(status int, from, to string) *RouteInfo |
Resource | (a *App) Resource(p string, r Resource) *App — RESTful resource mapping |
Mount | (a *App) Mount(p string, h http.Handler) — mount a stdlib handler |
ServeFiles | (a *App) ServeFiles(p string, root http.FileSystem) — static assets |
App — grouping and scoping#
| Method | Signature | Purpose |
|---|---|---|
Group | (a *App) Group(groupPath string) *App | Child app sharing the parent router; inherits cloned middleware stack |
VirtualHost | (a *App) VirtualHost(h string) *App | Create a vhost sub-router using gorilla/mux Host matching |
App — middleware#
| Method | Signature | Purpose |
|---|---|---|
Use | (a *App) Use(mw ...MiddlewareFunc) | Add middleware to this app/group |
MiddlewareStack (accessible via app.Middleware) exposes:
Use(mw ...MiddlewareFunc)— appendSkip(mw MiddlewareFunc, handlers ...Handler)— skip mw for specific handlersRemove(mws ...MiddlewareFunc)— remove from stack entirelyReplace(mw1, mw2 MiddlewareFunc)— swap in place (useful in tests)Clear()— wipe the stack
App — lifecycle#
| Method | Signature | Purpose |
|---|---|---|
Serve | (a *App) Serve(srvs ...servers.Server) error | Start HTTP server(s) and worker; block until shutdown |
Stop | (a *App) Stop(err error) error | Signal graceful shutdown |
ServeHTTP | (a *App) ServeHTTP(w http.ResponseWriter, r *http.Request) | Implement http.Handler; useful for testing |
App — introspection#
| Method | Signature | Purpose |
|---|---|---|
Routes | (a *App) Routes() RouteList | Return all registered routes |
RouteHelpers | (a *App) RouteHelpers() map[string]RouteHelperFunc | Build URL helper functions for templates |
Muxer | (a *App) Muxer() *mux.Router | Expose the underlying gorilla/mux router for advanced use |
Core types#
// Handler is the fundamental request processing unit.
type Handler func(Context) error
// MiddlewareFunc wraps a Handler; classic onion pattern.
type MiddlewareFunc func(Handler) Handler
// PreWare is a pre-Buffalo-middleware stdlib interceptor (runs before mux routing).
type PreWare func(http.Handler) http.HandlerContext interface#
The context interface passed to every handler:
type Context interface {
context.Context
Response() http.ResponseWriter
Request() *http.Request
Session() *Session
Cookies() *Cookies
Params() ParamValues
Param(string) string
Set(string, any)
LogField(string, any)
LogFields(map[string]any)
Logger() Logger
Bind(any) error
Render(int, render.Renderer) error
Error(int, error) error
Redirect(int, string, ...any) error
Data() map[string]any
Flash() *Flash
File(string) (binding.File, error)
}stdlib interop adapters#
// WrapHandler converts an http.Handler to a buffalo.Handler
func WrapHandler(h http.Handler) Handler
// WrapHandlerFunc converts an http.HandlerFunc to a buffalo.Handler
func WrapHandlerFunc(h http.HandlerFunc) HandlerResource interface — RESTful convention#
type Resource interface {
List(Context) error
Show(Context) error
Create(Context) error
Update(Context) error
Destroy(Context) error
}
// Optional extensions auto-detected at registration:
// New(Context) error → GET /resources/new
// Edit(Context) error → GET /resources/{id}/edit
// Optional middleware attachment:
type Middler interface {
Use() []MiddlewareFunc
}
// Default stub implementation:
type BaseResource struct{} // returns 404 for all methodsa.Resource("/users", &UsersResource{}) auto-generates:
| Method | Path | Handler |
|---|---|---|
| GET | /users | List |
| POST | /users | Create |
| GET | /users/new | New (optional) |
| GET | /users/{user_id} | Show |
| PUT | /users/{user_id} | Update |
| DELETE | /users/{user_id} | Destroy |
| GET | /users/{user_id}/edit | Edit (optional) |
render package (github.com/gobuffalo/buffalo/render)#
Engine constructor#
func New(opts Options) *EngineOptions includes: TemplatesFS, AssetsFS, Helpers, TemplateEngines (extensible map), DefaultContentType, TemplateMetadataKeys.
Renderer factories (package-level + Engine methods)#
Both global (use a default engine) and per-engine forms exist:
| Renderer | Package fn | Engine method | Content-Type |
|---|---|---|---|
| HTML template | HTML(names ...string) | e.HTML(names ...string) | text/html |
| JSON | JSON(v any) | e.JSON(v any) | application/json |
| XML | XML(v any) | e.XML(v any) | application/xml |
| Plain text template | Plain(names ...string) | e.Plain(names ...string) | text/plain |
| JavaScript template | JavaScript(names ...string) | e.JavaScript(names ...string) | application/javascript |
| String (inline) | String(s string, args ...any) | e.String(...) | text/html |
| File download | Download(ctx, name, r) | e.Download(ctx, name, r) | application/octet-stream |
| Generic template | Template(ct string, names ...string) | e.Template(ct, names) | configurable |
| Auto (content-negotiated) | Auto(ctx, i any) | e.Auto(ctx, i any) | negotiated |
| Custom func | Func(ct string, fn RendererFunc) | e.Func(ct, fn) | configurable |
| Server-Sent Events | NewEventSource(w) | — | text/event-stream |
| Markdown template | via MDTemplateEngine | registered as "md" engine | text/html |
| Go template | via GoTemplateEngine | registered as "tmpl" engine | configurable |
Renderer interface#
type Renderer interface {
ContentType() string
Render(io.Writer, Data) error
}
type RendererFunc func(io.Writer, Data) errorTemplate engine extension point#
// TemplateEngine signature allows registering custom rendering backends
// keyed by file extension in Engine.Options.TemplateEngines map.
type TemplateEngine func(input string, data map[string]any, helpers map[string]any) (string, error)servers package (github.com/gobuffalo/buffalo/servers)#
type Server interface {
Start(context.Context, http.Handler) error
}
// Constructors:
func NewSimple() *Simple // plain HTTP
func NewTLS(cert, key string) *TLS // HTTPS with cert files
func NewListener(l net.Listener) *Listener // pre-created listener
// Wrap functions for customising an existing *http.Server before passing to Buffalo:
func WrapSimple(s *http.Server) *Simple
func WrapTLS(s *http.Server, cert, key string) *TLS
func WrapListener(s *http.Server, l net.Listener) *Listenerworker package (github.com/gobuffalo/buffalo/worker)#
type Worker interface {
Register(string, Handler) error
Start(context.Context) error
Stop() error
Perform(Job) error
PerformAt(Job, time.Time) error
PerformIn(Job, time.Duration) error
}
type Handler func(Args) error
type Job struct { Handler string; Args Args; Queue string }
type Args map[string]any
// Default implementation:
type Simple struct{} // in-process goroutine-based queuebinding package (github.com/gobuffalo/buffalo/binding)#
// Register a content-type binder
func Register(contentType string, fn Binder)
// Bind a request body to a value
func Exec(req *http.Request, value any) error
// Extend time parsing
func RegisterTimeFormats(layouts ...string)
// Register custom type decoder
func RegisterCustomDecoder(fn CustomTypeDecoder, types []any, fields []any)
// Custom RequestBinder with non-global binders
func NewRequestBinder(binders ...ContenTypeBinder) *RequestBindermail package (github.com/gobuffalo/buffalo/mail)#
func NewMessage() Message
func NewFromData(data render.Data) Message
func New(c buffalo.Context) Message // populates from request context
// SMTP sender
func NewSMTPSender(host, port, user, password string) (SMTPSender, error)Plugin / Extension system#
Mechanism#
External binary IPC. Buffalo discovers plugins by executing buffalo-plugins available as a subprocess and parsing JSON output. Lifecycle events are dispatched to registered plugins via JSON over stdin/stdout. No Go plugin ABI or shared library linking.
Extension points for plugin authors#
Plugin authors use the plugcmds package to build their binary:
// Build a plugin binary:
a := plugcmds.NewAvailable()
a.Add("generate", &cobra.Command{...}) // mount under `buffalo generate`
a.Add("root", &cobra.Command{...}) // mount on `buffalo` root
a.Listen(func(e events.Event) error {...}) // listen to all lifecycle events
a.ListenFor("^app:", fn) // regex-filtered event listener
a.Mount(rootCmd) // wire into cobraPlugin metadata (JSON-encoded) includes: Name, BuffaloCommand, Description, Aliases, UseCommand, ListenFor.
Built-in lifecycle events emitted by App#
Events follow the gobuffalo/events package (string key + events.Event payload):
EvtAppStart— emitted beforeServe()starts serversEvtAppStop— emitted on graceful shutdown- Additional events can be emitted from handlers via
events.Emit()
API style assessment#
| Dimension | Observation |
|---|---|
| Fluent chaining | Route registration returns *RouteInfo (enables .Name(), .ResourceName), but Group() / Resource() return *App — a loose builder pattern rather than a true fluent DSL |
| Variadic factories | Serve(srvs ...servers.Server), Use(mw ...MiddlewareFunc) — idiomatic Go variadic for optional arguments |
| Interface-based extension | Worker, Server, Renderer, Context, Resource are all interfaces; swapping implementations requires no framework hooks |
| Dual API (global vs Engine) | render.JSON(v) works package-globally; engine.JSON(v) uses a configured engine — the global forms delegate to a default engine. Convenient but creates hidden global state |
| Backward compatibility | No explicit semver API promises. The in-flight Home extraction (v0→v1 refactor) introduces bridging fields (root, appSelf, children) that maintain compatibility while the public surface evolves |
| No generated code | Unlike gRPC or OpenAPI toolchains, Buffalo’s HTTP API surface is entirely hand-wired. No proto files, no go:generate directives for routing |