Gluo: PHP REST API Starter
Gluo (Esperanto for glue) is a production-ready PHP REST API starter: create a project you fully own, powered by an updatable framework core — so you focus on business logic, not infrastructure.
Why Use This?
Every new REST API needs the same boilerplate: authentication, migrations, an ORM, OpenAPI docs, a test harness, and a DI container. Setting all of that up correctly takes days — and it's not the work your users care about.
Gluo splits the problem the right way:
- Your project (
composer create-project byjg/gluo) — a full-stack monorepo: the PHP REST API at the repository root, an optional Vite + React frontend infrontend/, plusdocker-compose.ymlanddocker/. Generated once, renamed to your namespace, fully yours: change, remove, or replace anything. - The framework core (
byjg/gluo-core) — base classes, auth flow, attributes, code generator, and test harness live invendor/and improve with a plaincomposer update. No copy-paste to stay current.
And the API contract is never out of date: the OpenAPI attributes on your controllers generate openapi.json, which is at the same time the routing table and the contract every test checks responses against. An endpoint that is not documented does not exist, and a response that drifts from the documentation fails the test suite.
Quick Start
# Create your project (the installer asks a few questions — see below)
composer create-project byjg/gluo my-api ^7.0
# Start containers (API, the database server, and the frontend if you kept it)
cd my-api
docker compose up -d
# Run migrations
php gluo --env=dev migrate:reset
# Your API is ready!
curl http://localhost:8080/sample/ping
Commands like php gluo migrate:update, php gluo codegen:all, php gluo openapi, php gluo test,
and composer psalm run from the repository root — there is a single composer.json, and
the repository root is the PHP application root.
What you get
my-api/
├── composer.json # the single manifest (the repo root is the PHP app root)
├── src/ # Model, Repository, Service, Controller
├── config/ # dev / test / staging / prod
├── db/ # migrations + base.sql
├── public/ # the docroot: app.php, OpenAPI docs
├── templates/ # email + scriptify templates
├── tests/
├── frontend/ # optional Vite + React frontend (React 19 + Vite 6 + Tailwind)
├── docker/ # Dockerfile (API) + Dockerfile-html (frontend)
├── docker-compose.yml # API :8080, frontend :7080 (HTTPS :7443); includes the next file
├── docker-compose.database.yml # the database server (MySQL :3306, PostgreSQL :5432; none for SQLite)
└── README.md # quick start + link to the online documentation
The create-project installer offers two toggles:
- Install Frontend — keep the
frontend/SPA (login, password-reset, dashboard, and profile screens, wired to the API over JWT). Say no andfrontend/, its Docker image, and thefrontendcompose service are removed, leaving a pure API project. - Install Examples — keep the demo entities (
Project,Task,Note) and their frontend pages. Say no and you get a clean app shell (auth + profile only, no example CRUD).
| Install Examples: Yes | Install Examples: No | |
|---|---|---|
| Frontend: Yes | Full-stack demo (auth + example CRUD) | Auth-only app shell (login/profile) |
| Frontend: No | Pure API with example endpoints | Pure API, clean slate |
When the frontend is enabled, docker compose up -d serves it at http://localhost:7080
and, with a self-signed certificate, at https://localhost:7443
(via byjg/static-httpserver) while the API
answers on http://localhost:8080. See the Frontend guide →.
📚 Complete Getting Started Guide →
Architecture Overview
Key Features
- 🚀 Code generator — one command scaffolds Model, Repository, Service, REST controller, and tests from any database table
- 🏗️ Two patterns — choose Repository (DI + Service layer) or ActiveRecord per entity; mix them in the same project
- 🔐 Auth out of the box — JWT login, token refresh, password reset, and role-based access control (RBAC) included
- 📖 OpenAPI-first — routes are driven by
openapi.json; the API reference (Scalar), contract testing, and docs stay in sync automatically - 🗄️ Database migrations — versioned up/down SQL migrations with a one-command runner and ORM integration
- 🧪 In-process testing —
FakeApiRequesterruns the full API stack inside PHPUnit, no web server needed - 🎨 Optional React frontend — a Vite + React 19 + Tailwind SPA in
frontend/with login, password-reset, dashboard, and profile screens already wired to the API over JWT - 🐳 Docker ready — MySQL, PHP-FPM, Nginx, and the frontend pre-configured;
docker compose up -dand you're running - 🔄 Updatable core — framework fixes and features arrive with
composer update byjg/gluo-core; your code stays untouched - ⚙️ PSR standards — PSR-7 (HTTP messages), PSR-11 (container), PSR-6/16 (cache)
# Generate a complete CRUD API from a single table (run from the repo root)
php gluo --env=dev codegen:all --table=project --save
Documentation
Getting Started
- Installation & Setup – Install the starter, configure environments, and review prerequisites.
- Coming from another PHP framework (Laravel, Symfony, Drupal, CakePHP, CodeIgniter) – Concept and command mapping, plus the four things that genuinely work differently.
- Create Your First Table – Define your first migration and schema.
- Add Fields – Safely evolve existing tables.
- Create REST Endpoints – Generate REST handlers from your tables.
- Windows Setup – WSL/Windows-specific checklist.
- Unattended Setup – Automate installs for CI/CD pipelines.
Guides
- Frontend (Vite + React) – Run and customize the optional
frontend/SPA that talks to the API over JWT. - REST Controllers – Define routes with PHP attributes; keep controllers thin.
- Authentication – Configure JWT login flows and RBAC enforcement.
- Database Migrations – Version and run schema migrations in every environment.
- ORM – Use MicroORM for repository and ActiveRecord patterns.
- Service Layer – Organize business logic, orchestration, and transaction boundaries.
- Repository Patterns – Implement complex queries, UUID handling, and filtering helpers.
- Template Customization – Tailor the generator templates to match your coding standards.
- Testing – Unit, integration, and contract testing with
FakeApiRequester. - JWT Authentication Advanced – Extend tokens with custom claims and refresh logic.
- Error Handling – Map exceptions to HTTP responses and logging patterns.
- Configuration – Layer configurations, secrets, and environment overrides.
Concepts
- Architecture – Architectural decisions: when to use Repository vs ActiveRecord.
- OpenAPI Integration – How swagger-php, the spec file, and the API reference fit together.
- Dependency Injection – PSR-11 container, environment hierarchy, and DI binding patterns.
- Request Lifecycle – Trace an HTTP request from entry point to JSON response.
Reference
- Code Generator – Automate models, repositories, services, controllers, and tests.
- Attributes –
RequireAuthenticated,RequireRole,ValidateRequest, and custom attributes. - Traits – Timestamp and soft-delete helpers for models.
- The gluo Command –
php gluo: migrations, codegen, OpenAPI, and your own project commands. - Scriptify – REPL, CLI runner, and service manager utilities.
- Components – Full PHP component dependency graph.
AI coding agents
gluo-developer is an Agent Skill that teaches a coding agent how a Gluo project is built: the
two model patterns, codegen, the OpenAPI attributes, tests, migrations and the DI config. It is
published at opensource.byjg.com/docs/ai/agent-skills/gluo-developer.
- Claude Code: a project created from the starter declares the ByJG plugin catalog in
.claude/settings.json, so Claude Code offers the skill once you trust the project folder. To install it by hand:/plugin marketplace add byjg/skills, then/plugin install gluo-developer@byjg. - Other agents that read Agent Skills (Codex, Cursor, Gemini CLI, ...):
npx skills add byjg/skills --skill gluo-developer.
Real-World Example
# 1. Create database table (migrations live under db/)
cat > db/migrations/up/00002-create-products.sql << 'EOF'
CREATE TABLE products (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(100) NOT NULL,
price DECIMAL(10,2) NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
EOF
# 2. Run migration
php gluo --env=dev migrate:update
# 3. Generate all code
php gluo --env=dev codegen:all --table=products --save
# 4. Generate the OpenAPI spec so routing is active
php gluo openapi
# 5. Log in and capture the token
TOKEN=$(curl -s -X POST http://localhost:8080/login \
-H "Content-Type: application/json" \
-d '{"username":"[email protected]","password":"!P4ssw0rdstr!"}' \
| jq -r '.token')
# 6. Call your new endpoint
curl -s -H "Authorization: Bearer $TOKEN" http://localhost:8080/products | jq
You just created a complete CRUD API with:
- ✅ Model with validation
- ✅ Repository for data access
- ✅ Service for business logic
- ✅ REST controller with GET, POST, PUT endpoints
- ✅ Functional tests
- ✅ OpenAPI documentation
- ✅ JWT authentication
Requirements
- PHP 8.3+ (8.5 recommended)
- Docker & Docker Compose (optional but recommended)
- Composer
- Git
Support & Community
Your Code vs. the Framework
The starter generates a project that is fully yours — src/, config/, db/, frontend/, docker/:
- ✅ Full control over every file the generator gave you
- ✅ Base classes are thin extension points (
BaseLoginController,BaseRepository,BaseService, …) — override what you need - ✅ Framework improvements arrive via
composer update byjg/gluo-core - ✅ Remove what you don't need — the frontend, auth, examples, and patterns are all optional
License
This project is open source. See LICENSE for details.
Dependencies
📚 Complete Component Dependency Graph →
Running Tests
In this repository, docker-compose.yml, docker-compose.database.yml, db/base.sql and
db/migrations/ are not versioned: they are written from .db-dialects/
for one database. A created project gets them as its own files.
composer install
php gluo --env=dev db:dialect mysql # or postgres, sqlite
docker compose up -d --wait
php gluo test
See the testing guide for writing tests for your own endpoints.