2.9 KiB
2.9 KiB
title, impact, impactDescription, tags
| title | impact | impactDescription | tags |
|---|---|---|---|
| Set Up a Go-Extended PocketBase Application | HIGH | Foundation for all custom Go business logic, hooks, and routing | go, extending, setup, main, bootstrap |
Set Up a Go-Extended PocketBase Application
When extending PocketBase as a Go framework (v0.36+), the entry point is a small main.go that creates the app, registers hooks on OnServe(), and calls app.Start(). Avoid reaching for a global app variable inside hook handlers - use e.App instead so code works inside transactions.
Incorrect (global app reuse, no OnServe hook, bare http.Handler):
package main
import (
"log"
"net/http"
"github.com/pocketbase/pocketbase"
)
var app = pocketbase.New() // global reference used inside handlers
func main() {
// Routes registered directly via net/http - bypasses PocketBase's router,
// middleware chain, auth, rate limiter and body limit
http.HandleFunc("/hello", func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("hello"))
})
if err := app.Start(); err != nil {
log.Fatal(err)
}
}
Correct (register routes inside OnServe, use e.App in handlers):
package main
import (
"log"
"net/http"
"os"
"github.com/pocketbase/pocketbase"
"github.com/pocketbase/pocketbase/apis"
"github.com/pocketbase/pocketbase/core"
)
func main() {
app := pocketbase.New()
app.OnServe().BindFunc(func(se *core.ServeEvent) error {
// Serve static assets from ./pb_public (if present)
se.Router.GET("/{path...}", apis.Static(os.DirFS("./pb_public"), false))
// Custom API route - namespaced under /api/{yourapp}/ to avoid
// colliding with built-in /api/collections, /api/realtime, etc.
se.Router.GET("/api/myapp/hello/{name}", func(e *core.RequestEvent) error {
return e.JSON(http.StatusOK, map[string]string{
"message": "hello " + e.Request.PathValue("name"),
})
}).Bind(apis.RequireAuth())
return se.Next()
})
if err := app.Start(); err != nil {
log.Fatal(err)
}
}
Project bootstrap:
go mod init myapp
go mod tidy
go run . serve # development
go build && ./myapp serve # production (statically linked binary)
Key details:
- Requires Go 1.25.0+ (PocketBase v0.36.7+ bumped the minimum to Go 1.25.0).
- PocketBase ships with the pure-Go
modernc.org/sqlitedriver - no CGO required by default. - If you need FTS5, ICU, or a custom SQLite build, pass
core.DBConnectinpocketbase.NewWithConfig(...)- it is called twice (once forpb_data/data.db, once forpb_data/auxiliary.db). - Inside hooks, prefer
e.Appover a captured parent-scopeapp- the hook may run inside a transaction and the parentappwould deadlock.
Reference: Extend with Go - Overview