The most common task when using PocketBase as framework probably would be querying and working with your collection records.

    All available models.Record getter and setters are listed in the godoc of the model , but below you could find some examples:

    // export the public safe record fields as map[string]any record.PublicExport() // returns a new model copy populated with the original/intial record data // (could be useful if you want to compare old and new field values) record.OriginalCopy() // returns a copy of the current record model populated only // with its latest data state and everything else reset to the defaults record.CleanCopy() // set the value of a single record field record.Set("someField", 123) // bulk set fields from a map record.Load(data) // retrieve a single record field value record.Get("someField") // -> as any record.GetBool("someField") // -> as bool record.GetString("someField") // -> as string record.GetInt("someField") // -> as int record.GetFloat("someField") // -> as float64 record.GetTime("someField") // -> as time.Time record.GetDateTime("someField") // -> as types.DateTime record.GetStringSlice("someField") // -> as []string // unmarshal a single json field value into the provided result record.UnmarshalJSONField("someJsonField", &result) // retrieve a single or multiple expanded data record.ExpandedOne("author") // -> as nil|*models.Record record.ExpandedAll("categories") // -> as []*models.Record // auth records only // --- record.SetPassword("123456") record.ValidatePassword("123456") record.PasswordHash() // --- record.Username() record.SetUsername("john.doe") // --- record.Email() record.SetEmail("test@example.com") // --- record.EmailVisibility() record.SetEmailVisibility(false) // --- record.Verified() record.SetVerified(false) // --- record.TokenKey() record.SetTokenKey("ABCD123") record.RefreshTokenKey() // sets autogenerated TokenKey // --- record.LastResetSentAt() record.SetLastResetSentAt(types.DateTime{}) // --- record.LastVerificationSentAt() record.SetLastVerificationSentAt(types.DateTime{})
    // retrieve a single "articles" collection record by its id record, err := app.Dao().FindRecordById("articles", "RECORD_ID") // retrieve a single "articles" collection record by a single key-value pair record, err := app.Dao().FindFirstRecordByData("articles", "slug", "test") // retrieve a single "articles" collection record by a string filter expression // (use "{:placeholder}" to safely bind untrusted user input parameters) record, err := app.Dao().FindFirstRecordByFilter( "articles", "status = 'public' && category = {:category}", dbx.Params{ "category": "news" }, )
    // retrieve multiple "articles" collection records by their ids records, err := app.Dao().FindRecordsByIds("articles", []string{"RECORD_ID1", "RECORD_ID2"}) // retrieve multiple "articles" collection records by a custom dbx expression(s) records, err := app.Dao().FindRecordsByExpr("articles", dbx.NewExp("LOWER(username) = {:username}", dbx.Params{"username": "John.Doe"}), dbx.HashExp{"status": "pending"}, ) // retrieve multiple "articles" collection records by a string filter expression // (use "{:placeholder}" to safely bind untrusted user input parameters) records, err := app.Dao().FindRecordsByFilter( "articles", // collection "status = 'public' && category = {:category}", // filter "-publised", // sort 10, // limit 0, // offset dbx.Params{ "category": "news" }, // optional filter params )
    // retrieve a single auth collection record by its email user, err := app.Dao().FindAuthRecordByEmail("users", "test@example.com") // retrieve a single auth collection record by its username (case insensitive) user, err := app.Dao().FindAuthRecordByUsername("users", "John.Doe") // retrieve a single auth collection record by its JWT (auth, password reset, etc.) user, err := app.Dao().FindAuthRecordByToken("JWT_TOKEN", app.Settings().RecordAuthToken.Secret)

    In addition to the above read and write helpers, you can also create custom Record model queries using Dao.RecordQuery(collection) method. It returns a DB builder that can be used with the same methods described in the Database guide.

    import ( "github.com/pocketbase/dbx" "github.com/pocketbase/pocketbase/daos" "github.com/pocketbase/pocketbase/models" ) ... func FindActiveArticles(dao *daos.Dao) ([]*models.Record, error) { query := dao.RecordQuery("articles"). AndWhere(dbx.HashExp{"status": "active"}). OrderBy("published DESC"). Limit(10) records := []*models.Record{} if err := query.All(&records); err != nil { return nil, err } return records, nil }
    import ( "github.com/pocketbase/pocketbase/models" ) ... collection, err := app.Dao().FindCollectionByNameOrId("articles") if err != nil { return err } record := models.NewRecord(collection) // set individual fields // or bulk load with record.Load(map[string]any{...}) record.Set("title", "Lorem ipsum") record.Set("active", true) record.Set("someOtherField", 123) if err := app.Dao().SaveRecord(record); err != nil { return err }
    import ( "github.com/pocketbase/pocketbase/forms" "github.com/pocketbase/pocketbase/models" ) ... collection, err := app.Dao().FindCollectionByNameOrId("articles") if err != nil { return err } record := models.NewRecord(collection) form := forms.NewRecordUpsert(app, record) // or form.LoadRequest(r, "") form.LoadData(map[string]any{ "title": "Lorem ipsum", "active": true, "someOtherField": 123, }) // manually upload file(s) f1, _ := filesystem.NewFileFromPath("/path/to/file1") f2, _ := filesystem.NewFileFromPath("/path/to/file2") form.AddFiles("yourFileField1", f1, f2) // or mark file(s) for deletion form.RemoveFiles("yourFileField2", "demo_xzihx0w.png") // validate and submit (internally it calls app.Dao().SaveRecord(record) in a transaction) if err := form.Submit(); err != nil { return err }
    import ( "github.com/pocketbase/pocketbase/apis" "github.com/pocketbase/pocketbase/core" ) ... app.OnRecordBeforeCreateRequest("articles").Add(func(e *core.RecordCreateEvent) error { admin, _ := e.HttpContext.Get(apis.ContextAdminKey).(*models.Admin) if admin != nil { return nil // ignore for admins } // overwrite the submitted "active" field value to false e.Record.Set("active", false) // or you can also prevent the create event by returning an error, eg.: if (e.Record.GetString("status") != "pending") { return apis.NewBadRequestError("status must be pending", nil) } return nil })
    record, err := app.Dao().FindRecordById("articles", "RECORD_ID") if err != nil { return err } // set individual fields // or bulk load with record.Load(map[string]any{...}) record.Set("title", "Lorem ipsum") record.Set("active", true) record.Set("someOtherField", 123) if err := app.Dao().SaveRecord(record); err != nil { return err }
    import ( "github.com/pocketbase/pocketbase/forms" ) ... record, err := app.Dao().FindRecordById("articles", "RECORD_ID") if err != nil { return err } form := forms.NewRecordUpsert(app, record) // or form.LoadRequest(r, "") form.LoadData(map[string]any{ "title": "Lorem ipsum", "active": true, "someOtherField": 123, }) // validate and submit (internally it calls app.Dao().SaveRecord(record) in a transaction) if err := form.Submit(); err != nil { return err }
    import ( "github.com/pocketbase/pocketbase/apis" "github.com/pocketbase/pocketbase/core" ) ... app.OnRecordBeforeUpdateRequest("articles").Add(func(e *core.RecordUpdateEvent) error { admin, _ := e.HttpContext.Get(apis.ContextAdminKey).(*models.Admin) if admin != nil { return nil // ignore for admins } // overwrite the submitted "active" field value to false e.Record.Set("active", false) // or you can also prevent the create event by returning an error, eg.: if (e.Record.GetString("status") != "pending") { return apis.NewBadRequestError("status must be pending.", nil) } return nil })
    record, err := app.Dao().FindRecordById("articles", "RECORD_ID") if err != nil { return err } if err := app.Dao().DeleteRecord(record); err != nil { return err }
    titles := []string{"title1", "title2", "title3"} collection, err := app.Dao().FindCollectionByNameOrId("articles") if err != nil { return err } app.Dao().RunInTransaction(func(txDao *daos.Dao) error { // create new record for each title for _, title := range titles { record := models.NewRecord(collection) record.Set("title", title) if err := txDao.SaveRecord(record); err != nil { return err } } return nil })

    To expand record relations programmatically you can use the app.Dao().ExpandRecord(record, expands, customFetchFunc) or app.Dao().ExpandRecords(records, expands, customFetchFunc) methods.

    Once loaded, you can access the expanded relations via record.ExpandedOne(relName) or record.ExpandedAll(relName) methods.

    For example:

    record, err := app.Dao().FindFirstRecordByData("articles", "slug", "lorem-ipsum") if err != nil { return err } // expand the "author" and "categories" relations if errs := app.Dao().ExpandRecord(record, []string{"author", "categories"}, nil); len(errs) > 0 { return fmt.Errorf("failed to expand: %v", errs) } // print the expanded records log.Println(record.ExpandedOne("author")) log.Println(record.ExpandedAll("categories"))

    To check whether a custom client request or user can access a single record, you can use the app.Dao().CanAccessRecord(record, requestInfo, rule) method.

    For example:

    package main import ( "log" "net/http" "github.com/labstack/echo/v5" "github.com/pocketbase/pocketbase" "github.com/pocketbase/pocketbase/apis" "github.com/pocketbase/pocketbase/core" ) func main() { app := pocketbase.New() app.OnBeforeServe().Add(func(e *core.ServeEvent) error { e.Router.Add("GET", "/articles/:slug", func(c echo.Context) error { info := apis.RequestInfo(c) slug := c.PathParam("slug") record, err := app.Dao().FindFirstRecordByData("articles", "slug", slug) if err != nil { return apis.NewNotFoundError("", err) } canAccess, err := app.Dao().CanAccessRecord(record, info, record.Collection().ViewRule) if !canAccess { return apis.NewForbiddenError("", err) } return c.JSON(http.StatusOK, record) }) return nil }) if err := app.Start(); err != nil { log.Fatal(err) } }