The CWA is in heavy development
The CWA is still in alpha and not ready for production - some code and implementations are likely to change. If you would like to try out the CWA, please enjoy what we have provided and feel free to provide feedback, or get involved on GitHub.
DraftApi

Bundle Setup

Installing and configuring the Silverback API Components Bundle in a Symfony application.

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 extending AbstractUser
  • src/Entity/RefreshToken.php — the refresh token entity
  • config/packages/silverback_api_components.yaml — the bundle configuration
  • config/packages/security.yaml — a pre-wired security configuration
  • config/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.localnever 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:

ResourceEndpoint prefixPurpose
Layout/layoutsOuter page shell (header/footer)
Page/pagesIndividual pages with component groups
Route/routesURL → page/page data mapping
ComponentGroup/component_groupsNamed regions within a layout or page
ComponentPosition/component_positionsOrdered slot assignments
Collection/component/collectionsProxy to paginated resource lists
Form/component/formsSymfony form types via API

Your custom components are registered when you create entity classes extending AbstractComponent.