chamber-orchestra/view-bundle
Composer 安装命令:
composer require chamber-orchestra/view-bundle
包简介
Symfony bundle providing a typed, reusable view layer for building JSON API responses with automatic property binding and cache-warmed serialization
关键字:
README 文档
README
ChamberOrchestra View Bundle
A Symfony bundle that provides a typed view layer for JSON API responses. Define response shapes as PHP classes, return them from controllers, and let the bundle handle serialization automatically — no manual JsonResponse construction needed.
Built for Symfony 8.0 and PHP 8.5+, the bundle eliminates boilerplate in REST API controllers by introducing view models with automatic property binding, collection mapping, and production-ready cache warming.
Key Features
- Typed view models — define JSON response structures as PHP classes with typed properties
- Automatic property binding —
BindViewmaps domain object properties to view properties via reflection - Collection mapping —
IterableViewtransforms arrays and iterables with typed element views - Null stripping — null values are automatically excluded from serialized JSON output
- Build-time cache warming — pre-computed metadata and property mappings eliminate reflection overhead in production
- Build-versioned caching — cache files are tied to
container.build_idfor zero-downtime deployments - Doctrine proxy support — transparent lazy-load initialization before property access
Requirements
- PHP 8.5+
- Symfony 8.0 components (http-kernel, serializer, property-access, dependency-injection, config, framework-bundle)
- doctrine/common ^3.5
Installation
composer require chamber-orchestra/view-bundle:8.0.*
Enable the bundle in config/bundles.php:
return [ // ... ChamberOrchestra\ViewBundle\ChamberOrchestraViewBundle::class => ['all' => true], ];
Quick Start
Define a view model that maps properties from a domain object:
use ChamberOrchestra\ViewBundle\Attribute\BindsFrom; use ChamberOrchestra\ViewBundle\Attribute\Type; use ChamberOrchestra\ViewBundle\View\BindView; use ChamberOrchestra\ViewBundle\View\IterableView; #[BindsFrom(User::class)] final class UserView extends BindView { public string $id; public string $name; #[Type(ImageView::class)] public IterableView $images; public function __construct(User $user) { parent::__construct($user); } } final class ImageView extends BindView { public string $path; }
Return the view from a controller — the bundle converts it to a JsonResponse automatically:
#[Route('/user/me', methods: ['GET'])] final class GetMeAction { public function __invoke(): UserView { return new UserView($this->getUser()); } }
ViewSubscriber converts any ViewInterface result into a JsonResponse. Non-view results pass through unchanged.
View Types
| View | Purpose |
|---|---|
ResponseView |
Base response with HTTP status (200) and Content-Type: application/json headers |
DataView |
Wraps any view or array under a "data" key |
BindView |
Maps matching properties from a source object using reflection |
IterableView |
Maps collections via a callback or view class string |
KeyValueView |
Produces associative array output for metadata blocks |
BindView Property Binding
BindView uses BindUtils to synchronize properties between source objects and view instances. It handles:
- Built-in PHP types and custom objects
ViewInterfacesubclasses (auto-constructed)IterableViewproperties with#[Type(ViewClass::class)]attribute for typed collections- Skips union types and incompatible type pairs
Architecture
Request/Response Flow
- SetVersionSubscriber (priority 256) — injects the DI-managed
BindUtilsinstance intoBindViewviaBindView::setBindUtils() - Controller returns a
ViewInterfaceobject - ViewSubscriber — detects
ViewInterfaceresults, wraps non-ResponseViewInterfaceinDataView, serializes to JSON viaViewNormalizer
View Auto-Discovery
Views implementing ViewInterface are automatically tagged with chamber_orchestra.view via #[AutoconfigureTag]. The ViewPass compiler pass collects these classes and passes them to cache warmers for pre-computation.
Performance Optimizations
The bundle includes a two-phase optimization strategy for production environments:
Phase 1: Runtime Metadata Caching
ViewMetadataFactorycaches property metadata in memory- Direct property access eliminates repeated reflection calls
- 30-50% faster normalization on repeated calls
Phase 2: Build-Time Cache Warming
ViewMetadataCacheWarmerpre-computes view property metadata at build timeBindUtilsCacheWarmerpre-computes property mappings (uses#[BindsFrom]for targeted source classes, falls back to N² pairs)- Generated opcache-optimized PHP files stored in
kernel.share_dir - Cache files are versioned with
container.build_idfor safe deployments - 60-80% reduction in reflection overhead on production requests
- Automatic fallback to reflection when warmed cache is unavailable
Cache Configuration
BindUtils is registered as a DI service with $buildId, $debug, and $shareDir constructor arguments. When APP_DEBUG=false, property accessor caching is enabled with a 24-hour lifetime. SetVersionSubscriber injects the configured instance into BindView on each request.
Warm the cache in production:
bin/console cache:warmup --env=prod
This generates build-versioned files in the shared cache directory:
- View property metadata (nullability, defaults, types)
- View-to-view property mappings for
BindUtils
Benchmarks
PHPBench benchmarks are included to measure serialization performance and cache impact:
composer bench # Run all benchmarks vendor/bin/phpbench run --report=default # Run with default report
Benchmark classes: BindUtilsBench, CacheWarmupBench, NormalizationBench.
Development
composer install # Install dependencies composer test # Run all tests (93 tests, 328 assertions) ./bin/phpunit # Run tests directly ./bin/phpunit --filter X # Run specific test class or method
License
MIT
统计信息
- 总下载量: 2.73k
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 227
- 点击次数: 0
- 依赖项目数: 5
- 推荐数: 1
其他信息
- 授权协议: MIT
- 更新时间: 2025-12-29