API-skeleton first

Production PHP APIs, explicit by default.

A high-performance framework with routing, context-aware DI, auth, queues, uploads, and generated OpenAPI docs — no hidden magic, no bloated core. Start from glueful/api-skeleton and add official extensions as your app grows.

$router->post('/users', [UserController::class, 'store'])
    ->middleware(['auth', 'rate_limit'])
    ->name('users.store');
MIT licensed OpenAPI built-in Context-aware DI First-class CLI 13 official extensions 40k+ resp/sec

Getting started

Up and running in seconds

Scaffold the API skeleton and start a real server — SQLite, queues, and OpenAPI are configured out of the box.

php glueful serve migrate:run
Create a project
$ composer create-project glueful/api-skeleton my-api
Start the server
$ cd my-api && php glueful serve

A CLI for everything

Scaffold code, run migrations and workers, and generate docs — one consistent php glueful entrypoint.

scaffold:controller migrate:run queue:work generate:openapi

Explicit routing, DI & auth

Context-aware services, attribute routing, and JWT / session / API-key auth over a pluggable user store.

ApplicationContext #[Controller] #[RequireScope]

Queues, OpenAPI & extensions

Background jobs, generated OpenAPI + typed SDKs, and an official extension ecosystem you add as you grow.

queue:work generate:openapi --ui glueful/aegis

A request has one clear path

Thin controllers, validation in DTOs, business logic in services, data access in repositories — easy to read, easy to test, with no hidden magic or global state.

  • Thin controllers that just shape the response
  • Validation in DTOs, orchestration in services
  • Context-aware DI — no hidden globals
  • N+1 detection & query caching built in

Explore the architecture

$router->post('/users', [UserController::class, 'store'])
    ->middleware(['auth', 'rate_limit']);

Out of the box

What you get immediately

The starter path shortens the gap between “new project” and “working API with operational basics.”

Scaffolding

Generate controllers, models, DTOs, jobs, rules, tests, factories, seeders, filters, and middleware with the scaffold commands.

API documentation

generate:openapi --ui produces your spec and a browsable UI — no separate docs stack to maintain.

Operational defaults

Health checks, security scanning, route diagnostics, queue presets, and deployment-oriented config from the start.

Rate limiting

Per-route, builder-configured throttling with sliding-window algorithms and pluggable storage.

Field selection

GraphQL-style fields and expand projection with depth limits and whitelist protection.

Testing

PHPUnit 10 with a real booted app for feature tests and a lightweight SQLite harness for libraries.

Official packages

Grow with official extensions

Keep the core lean; add product capabilities as Composer packages when you need them.

Auth

Identity & access

Authenticate users and authorize every request — a pluggable user store, role-based access control, and OAuth / SSO.

Messaging

Reach your users

Transactional email, push notifications, and SMS / WhatsApp messaging from one consistent delivery API.

Data & billing

Search & payments

Full-text search and a unified payment-gateway bridge — added as Composer packages when you need them.

Runtime

Performance at scale

Run long-lived PHP processes on RoadRunner, Swoole, or FrankenPHP for higher throughput on the same code.

Platform

Platform capabilities

Optional core subsystems — image processing, edge caching, supervised worker fleets, and table archiving — extracted from core so you add them only when you need them.

Quickstart

From new project to first endpoint in minutes

Scaffold the skeleton, generate a controller, and ship documented JSON — in a handful of commands, no boilerplate to wire up first.

Read the quickstart

$ composer create-project glueful/api-skeleton my-api
Installing dependencies… done
$ cd my-api && php glueful serve
✓ Server running http://localhost:8000
$ php glueful scaffold:controller Post --api
✓ Created PostController
$ curl localhost:8000/api/posts
{"success":true,"data":[]}