bednic/api-skeleton
Composer 安装命令:
composer create-project bednic/api-skeleton
包简介
ReactPHP + SlimPHP + Doctrine2 ORM + PHP DI + JSON API skeleton for building REST API's.
README 文档
README
A template skeleton for building HTTP-based APIs in PHP — REST, JSON:API, JSON-RPC, or plain HTTP/JSON. It ships a long-running ReactPHP HTTP server, Slim routing, a PHP-DI container, Doctrine ORM persistence, and the jaspr/mapper JSON:API engine, arranged in a strict Clean Architecture layout.
Scaffold a new project with:
composer create-project bednic/api-skeleton my-api
Tech stack
| Concern | Library |
|---|---|
| Runtime | PHP 8.4, ReactPHP HTTP server (long-running, event loop) |
| HTTP / routing | Slim 4 (slim/slim, slim/psr7, slim/http) |
| DI container | PHP-DI 7 |
| Persistence | Doctrine ORM 3 + DBAL 4 + Migrations 3, PostgreSQL |
| JSON:API | jaspr/mapper (JSON:API 1.1: parsing, encoding, routing, OpenAPI/TS generation) |
| Object mapping | jolicode/automapper |
| Identifiers | ramsey/uuid (+ Doctrine type) |
| Auth | firebase/php-jwt |
| Logging / monitoring | Monolog 3, Sentry |
| CLI | Symfony Console |
| Config | Symfony Dotenv (12-factor env vars) |
| Caching | Symfony Cache (PSR-6 / PSR-16), APCu in production |
Architecture
The project follows Clean Architecture with three layers (see CONSTITUTION.md §III). Dependencies point inward — the Business layer knows nothing of the outer layers.
- Application (
src/Application) — the port to the outside world: HTTP routers, controllers, CLI commands, middleware, error rendering. Uses the interfaces the Business layer provides. - Business (
src/Business) — core domain: Aggregates, Aggregate Roots, value objects, and Processes that fulfil use-cases. Depends on no other layer. - Infrastructure (
src/Infrastructure) — external concerns: database, mapping, third-party I/O. Implements the interfaces the Business layer requires (dependency inversion).
src/
├── Application/ # access layer (ports)
│ ├── ApplicationFactory.php # builds the Slim App (health route, OPTIONS, ...)
│ ├── Web/ # ReactPHP server bootstrap + route registrars
│ ├── Cli/ # Symfony Console bootstrap
│ │ └── Command/ # ← add console commands here
│ ├── Resource/ # ← add JSON:API resource definitions here
│ ├── Middleware/ # PSR-15 middleware (CORS, auth, access log, Sentry, ...)
│ └── Exception/ # ApplicationError / ApplicationException
├── Business/ # domain core (no outward dependencies)
│ ├── Aggregate/ # EntityInterface, RootEntityInterface, Timestamp
│ ├── Process/ # ProcessInterface — business use-cases
│ ├── ValueObject/ # Comparable and your VOs
│ └── Exception/ # BusinessError / BusinessException
├── Infrastructure/ # adapters implementing Business interfaces
│ ├── ContainerFactory.php # builds the PHP-DI container from config/
│ ├── Mapper/ # AutoMapper factory + transformers
│ └── Persistence/
│ ├── Doctrine/ # EntityManager factory, decorator, config, query helpers
│ ├── Repository/ # ← add Aggregate Root repositories here
│ ├── Migration/ # ← Doctrine migrations live here
│ └── Type/ # ← add custom Doctrine DBAL types here
├── const.php # path & environment-name constants
└── sentry.php # Sentry initialization
The empty *.md files (RESOURCE.md, REPOSITORY.md, MIGRATION.md, TYPE.md, COMMAND.md) mark the extension points where your own code goes.
Getting started
# 1. scaffold
composer create-project bednic/api-skeleton my-api
cd my-api
# 2. configure environment (12-factor; see CONSTITUTION.md §XII)
cp .env .env.local # override secrets/connection in .env.local (gitignored)
# 3. run the full stack (api + postgres + traefik)
docker compose up
The API is then reachable through the Traefik proxy at http://api.localhost, with the Traefik dashboard at http://localhost:8080. A GET /health endpoint returns ok.
Running
| What | How |
|---|---|
| HTTP server (prod) | Container entrypoint runs php src/Application/Web/bootstrap.php, which boots the ReactPHP HttpServer on port 80. |
| HTTP server (dev) | The dev image entrypoint runs the same bootstrap under nodemon for hot-reload on file changes (config in nodemon.json). |
| CLI | php bin/cli — the Symfony Console application (src/Application/Cli/bootstrap.php). |
| DB migrations | vendor/bin/doctrine-migrations <cmd> using migrations.php (e.g. diff, migrate). |
Adding skeleton parts
Define a JSON:API resource
Resources are plain classes annotated with JSONAPI\Mapper\Annotation\*, placed in src/Application/Resource/. Routes, OpenAPI, and (de)serialization are generated from this metadata — you do not hand-write routing. Each resource wraps a domain entity and exposes its fields:
#[Resource(type: 'users', operations: [Operation::READ, Operation::LIST])]
class UserResource
{
#[Id] public string $id;
#[Attribute] public string $name;
#[Relationship(GroupResource::class, operations: [Operation::READ])]
public GroupResource $group;
}
Full reference — metadata, parser/encoder chains, controller patterns, OData filtering, metadata-driven routing — in .ai/jaspr-mapper.md.
Model the domain (Business layer)
- Implement
RootEntityInterfacefor Aggregate Roots andEntityInterfacefor inner entities (src/Business/Aggregate). Follow the Aggregate rules inCONSTITUTION.md§IX. - Put use-cases behind
ProcessInterface(src/Business/Process). - Define the repository/port interfaces the Business layer needs here; implement them in Infrastructure.
Persist it (Infrastructure layer)
- Add repositories in
src/Infrastructure/Persistence/Repository/. Inject theEntityManagerProvider(the factory), notEntityManagerInterface, and callgetDefaultManager()per operation. PreferEntityManager+QueryBuilderover Doctrine's nativeEntityRepository. - Custom DBAL types go in
Type/; register them inDoctrineConfigurationFactory. - Generate migrations into
Migration/.
Why the provider indirection and the cacheless decorator matter for a long-running, scaled server is explained in .ai/reactphp-doctrine.md.
Add a CLI command
Create a Symfony Console command in src/Application/Cli/Command/ and register it in src/Application/Cli/bootstrap.php.
Add middleware
PSR-15 middleware lives in src/Application/Middleware/ (CORS, authorization, access logging, Sentry performance are provided as examples) and is wired through the DI container.
Testing
PHPUnit 13, with two suites split to mirror src/ (see CONSTITUTION.md §V — behavior over coverage):
tests/
├── Unit/ # isolated domain rules, aggregates, business logic (namespace Unit\)
└── E2E/ # end-to-end / contract tests against the API (namespace E2E\)
composer test # run all suites
vendor/bin/phpunit --testsuite Unit
vendor/bin/phpunit --testsuite E2E
Each suite has its own bootstrap.php; the suites and bootstraps are configured in phpunit.xml.
Code quality & releases
| Command | Purpose |
|---|---|
composer analyse | PHP_CodeSniffer (PSR-12 + strict types) — phpcs.xml |
composer lint | Auto-fix style with phpcbf |
vendor/bin/rector | Automated refactors / upgrades — rector.php |
composer release | Cut a release with commit-and-tag-version — .versionrc.cjs |
Releases follow Semantic Versioning and commits follow Conventional Commits (CONSTITUTION.md §VII, §VIII). Linting/formatting is enforced by tooling, not manual review (§XIV).
Configuration
Configuration is strictly separated from code and supplied by the environment (12-factor). Defaults live in .env; override secrets and connection details in .env.local (gitignored). Docker Compose loads both. The DI container is assembled in config/definition.php, with per-environment overrides in config/definition.development.php and config/definition.test.php.
Development principles
This skeleton encodes a CONSTITUTION.md you are expected to uphold. Hard (non-negotiable) constraints: KISS, Clean Architecture, SOLID, meaningful testing, SemVer, Conventional Commits, centralized structured error handling & logging, secret management, environment independence, API-first documentation (OpenAPI), and automated linting. Soft (advisory) constraints: DRY and DDD aggregates — both may be relaxed when documented and justified for simplicity.
Reference docs
Deep-dive documentation for AI agents and contributors lives in .ai/:
.ai/jaspr-mapper.md— the JSON:API engine: metadata, parsing, encoding, routing, generators..ai/reactphp-doctrine.md— the self-healing, cacheless EntityManager pattern for the long-running scaled server.
统计信息
- 总下载量: 13
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 0
- 点击次数: 2
- 依赖项目数: 0
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2019-05-28