aepbase
A dynamic API backend that follows the AEP (API Enhancement Proposals) standard. Define resources at runtime via a meta-API and get fully functional CRUD endpoints, a SQLite database, and an OpenAPI 3.1 spec.
Features
- Dynamic resource definitions — create, update, and delete resource types through the API itself
- Automatic CRUD — each resource gets Create, Read, Update (PATCH), Apply (PUT), Delete, and List endpoints
- Nested resources — define parent-child relationships (e.g.
/publishers/{id}/books/{id})
- Custom methods — add arbitrary POST/GET actions on resources following AEP-136 (e.g.
/books/{id}:archive)
- OpenAPI 3.1 — auto-generated spec served at
/openapi.json, enriched with descriptions, examples, error responses, and tags
- SQLite with WAL — lightweight, zero-config persistence
- CORS support — configurable allowed origins
Quick Start
Build and run
go build -o aepbase ./
./aepbase
Server starts at http://localhost:8080.
CLI flags
| Flag |
Default |
Description |
-port |
8080 |
Listen port |
-db |
aepbase.db |
SQLite database path |
-cors-allowed-origins |
https://ui.aep.dev |
Comma-separated allowed origins (* for all). Replaces the default. |
-disable-cors |
false |
Disable CORS entirely (no Access-Control-* headers) |
Define a resource
aepbase exposes a standard REST API. Define a resource with a single POST:
curl -X POST http://localhost:8080/aep-resource-definitions \
-H "Content-Type: application/json" \
-d '{
"singular": "book",
"plural": "books",
"description": "A book published by a publisher.",
"examples": {
"title": "The Great Gatsby",
"author": "F. Scott Fitzgerald"
},
"schema": {
"type": "object",
"properties": {
"title": {"type": "string", "description": "The title of the book."},
"author": {"type": "string", "description": "The author of the book."}
}
}
}'
aepbase now serves full CRUD at /books and an updated OpenAPI spec at /openapi.json. The description, examples, and property-level description fields are optional — when provided, they enrich the generated OpenAPI spec with documentation and examples for every operation.
Using aepcli
Since aepbase generates an OpenAPI spec, you can use aepcli to interact with it instead of writing curl commands by hand. aepcli reads the spec and gives you typed commands for every resource automatically.
go install github.com/aep-dev/aepcli/cmd/aepcli@latest
Point it at the OpenAPI endpoint:
API="http://localhost:8080/openapi.json"
CRUD operations
# Create
aepcli $API book create 1984 \
--title "1984" \
--author "George Orwell"
# List
aepcli $API book list
# Get
aepcli $API book get 1984
# Update
aepcli $API book update 1984 \
--title "Nineteen Eighty-Four"
# Delete
aepcli $API book delete 1984
Nested resources
# Define a child resource
aepcli $API aep-resource-definition create chapter \
--singular chapter \
--plural chapters \
--parents book \
--schema '{"type":"object","properties":{"title":{"type":"string"},"number":{"type":"integer"}}}'
# Create a chapter under a book
aepcli $API chapter --book 1984 create ch1 \
--title "Part One" \
--number 1
# List chapters
aepcli $API chapter --book 1984 list
Custom methods
Custom methods use the :method syntax:
aepcli $API book :publish 1984
aepcli $API book :purchase 1984 \
--quantity 3
Web UI
You can browse and manage your resources through AEP Explorer, a web UI for AEP-compliant APIs. https://ui.aep.dev is allowed by CORS by default, so just open ui.aep.dev and paste in your OpenAPI URL:
http://localhost:8080/openapi.json
The UI will discover all your resources and let you create, read, update, and delete them without writing any commands.
Use as a library
aepbase can be embedded in your own Go server to add custom methods and logic:
package main
import (
"net/http"
"github.com/rambleraptor/aepbase/pkg/aepbase"
"github.com/rambleraptor/aepbase/pkg/db"
)
func main() {
database, _ := db.Init("app.db")
state := aepbase.NewState(database, "http://localhost:8080")
state.AddCustomMethod("book", "archive", aepbase.CustomMethodConfig{
Method: "POST",
Handler: func(w http.ResponseWriter, r *http.Request) {
// your logic here
},
})
http.ListenAndServe(":8080", state.Handler())
}
See examples/bookstore/ for a full working example with custom methods and an end-to-end demo script.
Project Structure
main.go # Standalone server
pkg/
aepbase/ # Core orchestration and state management
db/ # SQLite schema management
meta/ # Meta-API handlers (definitions CRUD)
resource/ # Dynamic resource CRUD handlers and validation
examples/
bookstore/ # Example app with custom methods and demo script
docs/
custom-methods.md # Custom methods guide
Running Tests
go test ./...
License
MIT