Documentation Index
Fetch the complete documentation index at: https://mintlify.com/magooney-loon/pb-ext/llms.txt
Use this file to discover all available pages before exploring further.
AST Parsing System
The AST (Abstract Syntax Tree) parsing system is the core of pb-ext’s automatic OpenAPI documentation generation. It analyzes your Go source code at startup to extract handler metadata, request/response schemas, and parameters without requiring manual annotations.Overview
The AST parser uses Go’sgo/ast and go/parser packages to analyze source files marked with the // API_SOURCE directive. It extracts:
- Handler function signatures and return types
- Request body types (from
BindBodyandjson.Decode) - Response schemas (from
c.JSON()calls) - Query, header, and path parameters
- Authentication requirements
- Struct definitions for component schemas
File Structure
The AST parser is split across multiple files by responsibility:| File | Purpose |
|---|---|
ast.go | Entry points: NewASTParser, DiscoverSourceFiles, ParseFile, EnhanceEndpoint |
ast_func.go | Handler and function analysis: extracting handlers, return types, parameters |
ast_struct.go | Struct analysis and schema generation |
ast_metadata.go | Value and type resolution: map literals, expressions, type aliases |
ast_file.go | File-level utilities: module path resolution, import following |
Handler Detection
A function is recognized as a PocketBase handler if it matches this exact signature:map[string]ast.Expr — variable name → RHS AST node for deep analysis
map[string][]MapKeyAdd — dynamic mapVar["key"] = value assignments
Two-Pass Struct Extraction
Struct extraction uses a two-pass approach to handle cross-references correctly: Pass 1: Register all structs with fields (no schemas) and type aliasesJSONSchema for each struct now that all names are known
- Resolves
$refpointers to other structs - Flattens embedded struct fields
- Handles pointer fields with
nullable: true
Request Detection
The parser detects request bodies from these patterns:handlerInfo.Variables.
Response Detection
Response schemas are extracted fromc.JSON(status, expr) calls:
- Try composite literal analysis (map/struct/slice)
- If argument is a variable, trace to its stored expression
- Merge any
MapAdditionsfor that variable - Fall back to type inference →
$reffor known structs - Last resort: generic object schema
Parameter Detection
The parser detects parameters in two passes:Pass 1: Direct Body Scan
| Pattern | Source |
|---|---|
q := e.Request.URL.Query(); q.Get("param") | query |
e.Request.URL.Query().Get("param") | query |
e.Request.URL.Query()["param"] | query |
info.Query["param"] (via e.RequestInfo()) | query |
e.Request.Header.Get("name") | header |
info.Headers["name"] (via e.RequestInfo()) | header |
e.Request.PathValue("id") | path (Required: true) |
Pass 2: Indirect Helper Scan
The parser automatically detects parameters read by helper functions: Domain helpers — literal param names:Function Return Type Resolution
extractFuncReturnTypes() runs before handler analysis to enable type inference:
ASTParser.funcReturnTypes as map[string]string (func name → Go type).
Helper Function Body Analysis
For functions returningmap[string]any or []map[string]any, the parser deep-analyzes the function body:
- Creates temporary
ASTHandlerInfoto track variables - Finds all
map[string]any{...}literals - Picks the literal with most keys (primary response shape)
- Finds variable name via
findAssignedVariable() - Merges dynamic
mapVar["key"] = valueadditions - For
[]map[string]any, wraps item schema in array
funcBodySchemas for reuse during response analysis.
Append-Based Slice Resolution
When handlers build slices viaappend(), the parser connects the item expression:
trackVariableAssignment()detectsvarName = append(varName, itemExpr)- Stores
itemExprinSliceAppendExprs[varName] enrichArraySchemaFromAppend()resolves item schema from stored expression
Auto-Import Following
After parsing all// API_SOURCE files, the parser automatically resolves local imports to find struct definitions:
- Reads
go.modfor module path (e.g.,github.com/user/myapp) - Collects imports from all
// API_SOURCEfiles - Strips module prefix → local directory path
- Skips already-parsed directories
- Calls
parseDirectoryStructs()to extract structs only (no handlers)
Zero-config — no directives needed on type files. External imports are ignored.
Source File Directives
| Directive | Where | Purpose |
|---|---|---|
// API_SOURCE | Top of .go file | Marks file for AST parsing |
// API_DESC <text> | Function doc comment | Handler description in OpenAPI |
// API_TAGS <csv> | Function doc comment | Comma-separated endpoint tags |
Debug Endpoint
Inspect the full AST parser state at runtime:- All parsed structs and their schemas
- All detected handlers and their metadata
- Per-version endpoints
- Component schemas
- Complete OpenAPI output
Common Patterns
Anonymous Struct Request Body
Index Expression Resolution
When a helper reads from another helper’s return:Variable Tracing
Parser Lifecycle
Performance
AST parsing happens once at startup. Specs are cached in memory. For production builds, use pre-generated specs from disk (see Spec Generation).Further Reading
- Spec Generation - Build-time spec generation
- Middleware - Custom middleware patterns
- Reserved Routes - Protected pb-ext routes