Bundle Setup
The API Components Bundle is the Symfony backend of CWA. It wires together API Platform, Doctrine ORM, LexikJWTAuthenticationBundle, Mercure, and a suite of content management abstractions so you spend your time building your app rather than infrastructure.
Prerequisites
- PHP 8.2+
- Symfony 7.4+
- Doctrine ORM
- API Platform 4.x
Installation
composer require silverback/api-components-bundle
The Flex recipe runs automatically and creates:
src/Entity/User.php— your user entity extendingAbstractUsersrc/Entity/RefreshToken.php— the refresh token entityconfig/packages/silverback_api_components.yaml— the bundle configurationconfig/packages/security.yaml— a pre-wired security configurationconfig/jwt/— directory for JWT keys (generated in the next step)
Generate JWT Keys
The bundle uses cookie-based JWT tokens for authentication. Generate a key pair once per environment:
mkdir -p config/jwt
openssl genpkey -out config/jwt/private.pem -aes256 -algorithm rsa -pkeyopt rsa_keygen_bits:4096
openssl pkey -in config/jwt/private.pem -out config/jwt/public.pem -pubout
Add the passphrase to .env.local — never commit this file:
JWT_PASSPHRASE=your_secure_passphrase
Add the key paths to .env:
JWT_SECRET_KEY=%kernel.project_dir%/config/jwt/private.pem
JWT_PUBLIC_KEY=%kernel.project_dir%/config/jwt/public.pem
Minimum Configuration
Open config/packages/silverback_api_components.yaml. At minimum you need:
silverback_api_components:
website_name: My CWA App
user:
class_name: App\Entity\User
publishable:
permission: "is_granted('ROLE_ADMIN')"
refresh_token:
handler_id: silverback.api_components.refresh_token.storage.doctrine
options:
class: App\Entity\RefreshToken
cookie_name: api_components
ttl: 604800 # 1 week in seconds
database_user_provider: database
Database Setup
The bundle adds tables for layouts, pages, routes, component groups, component positions, media objects, refresh tokens, and your user and component entities.
bin/console doctrine:migrations:diff
bin/console doctrine:migrations:migrate
Review the generated migration before running it — the initial migration is sizeable.
Environment Variables
Set these in .env (public) and .env.local (secrets):
# Database
DATABASE_URL="postgresql://user:pass@localhost:5432/app?serverVersion=16&charset=utf8"
# JWT auth
JWT_SECRET_KEY=%kernel.project_dir%/config/jwt/private.pem
JWT_PUBLIC_KEY=%kernel.project_dir%/config/jwt/public.pem
JWT_PASSPHRASE=your_passphrase
# Mercure (real-time updates)
MERCURE_URL=http://localhost:3000/.well-known/mercure
MERCURE_PUBLIC_URL=https://yourdomain.com/.well-known/mercure
MERCURE_JWT_SECRET=your_mercure_secret
# Email
MAILER_DSN=smtp://localhost:1025
Verifying the Install
Start your Symfony server and visit /api — you should see the API Platform documentation UI listing all available resources. The entrypoint at /_/entrypoint returns IRIs for every resource collection.
Create your first admin user — pass --admin so the account has ROLE_ADMIN access:
bin/console silverback:api-components:user:create --admin
Follow the prompts to set username, email, and password. Without the flag the account is created with ROLE_USER only and cannot access the admin panel. Then load any fixtures you've defined:
bin/console doctrine:fixtures:load
What Gets Auto-Registered
You don't need to register these — the bundle provides them out of the box:
| Resource | Endpoint prefix | Purpose |
|---|---|---|
| Layout | /layouts | Outer page shell (header/footer) |
| Page | /pages | Individual pages with component groups |
| Route | /routes | URL → page/page data mapping |
| ComponentGroup | /component_groups | Named regions within a layout or page |
| ComponentPosition | /component_positions | Ordered slot assignments |
| Collection | /component/collections | Proxy to paginated resource lists |
| Form | /component/forms | Symfony form types via API |
Your custom components are registered when you create entity classes extending AbstractComponent.