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 / TypeSignaturePurpose
Newfunc New(opts Options) *AppConstruct and configure a Buffalo application
NewOptionsfunc NewOptions() OptionsReturn an Options struct with sensible defaults

App — routing methods#

All HTTP methods return *RouteInfo which can be further configured (name, resource name, etc.):

MethodSignature
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#

MethodSignaturePurpose
Group(a *App) Group(groupPath string) *AppChild app sharing the parent router; inherits cloned middleware stack
VirtualHost(a *App) VirtualHost(h string) *AppCreate a vhost sub-router using gorilla/mux Host matching

App — middleware#

MethodSignaturePurpose
Use(a *App) Use(mw ...MiddlewareFunc)Add middleware to this app/group

MiddlewareStack (accessible via app.Middleware) exposes:

  • Use(mw ...MiddlewareFunc) — append
  • Skip(mw MiddlewareFunc, handlers ...Handler) — skip mw for specific handlers
  • Remove(mws ...MiddlewareFunc) — remove from stack entirely
  • Replace(mw1, mw2 MiddlewareFunc) — swap in place (useful in tests)
  • Clear() — wipe the stack

App — lifecycle#

MethodSignaturePurpose
Serve(a *App) Serve(srvs ...servers.Server) errorStart HTTP server(s) and worker; block until shutdown
Stop(a *App) Stop(err error) errorSignal graceful shutdown
ServeHTTP(a *App) ServeHTTP(w http.ResponseWriter, r *http.Request)Implement http.Handler; useful for testing

App — introspection#

MethodSignaturePurpose
Routes(a *App) Routes() RouteListReturn all registered routes
RouteHelpers(a *App) RouteHelpers() map[string]RouteHelperFuncBuild URL helper functions for templates
Muxer(a *App) Muxer() *mux.RouterExpose 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.Handler

Context 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) Handler

Resource 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 methods

a.Resource("/users", &UsersResource{}) auto-generates:

MethodPathHandler
GET/usersList
POST/usersCreate
GET/users/newNew (optional)
GET/users/{user_id}Show
PUT/users/{user_id}Update
DELETE/users/{user_id}Destroy
GET/users/{user_id}/editEdit (optional)

render package (github.com/gobuffalo/buffalo/render)#

Engine constructor#

func New(opts Options) *Engine

Options 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:

RendererPackage fnEngine methodContent-Type
HTML templateHTML(names ...string)e.HTML(names ...string)text/html
JSONJSON(v any)e.JSON(v any)application/json
XMLXML(v any)e.XML(v any)application/xml
Plain text templatePlain(names ...string)e.Plain(names ...string)text/plain
JavaScript templateJavaScript(names ...string)e.JavaScript(names ...string)application/javascript
String (inline)String(s string, args ...any)e.String(...)text/html
File downloadDownload(ctx, name, r)e.Download(ctx, name, r)application/octet-stream
Generic templateTemplate(ct string, names ...string)e.Template(ct, names)configurable
Auto (content-negotiated)Auto(ctx, i any)e.Auto(ctx, i any)negotiated
Custom funcFunc(ct string, fn RendererFunc)e.Func(ct, fn)configurable
Server-Sent EventsNewEventSource(w)text/event-stream
Markdown templatevia MDTemplateEngineregistered as "md" enginetext/html
Go templatevia GoTemplateEngineregistered as "tmpl" engineconfigurable

Renderer interface#

type Renderer interface {
    ContentType() string
    Render(io.Writer, Data) error
}
type RendererFunc func(io.Writer, Data) error

Template 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) *Listener

worker 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 queue

binding 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) *RequestBinder

mail 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 cobra

Plugin 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 before Serve() starts servers
  • EvtAppStop — emitted on graceful shutdown
  • Additional events can be emitted from handlers via events.Emit()

API style assessment#

DimensionObservation
Fluent chainingRoute registration returns *RouteInfo (enables .Name(), .ResourceName), but Group() / Resource() return *App — a loose builder pattern rather than a true fluent DSL
Variadic factoriesServe(srvs ...servers.Server), Use(mw ...MiddlewareFunc) — idiomatic Go variadic for optional arguments
Interface-based extensionWorker, 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 compatibilityNo 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 codeUnlike gRPC or OpenAPI toolchains, Buffalo’s HTTP API surface is entirely hand-wired. No proto files, no go:generate directives for routing