danielburger1337/bff-proxy-bundle
Install the Bundle
composer require danielburger1337/bff-proxy-bundle
Enable the bundle in config/bundles.php:
return [
// ...
DanielBurger1337\BffProxyBundle\BffProxyBundle::class => ['all' => true],
];
Configure Upstream Services
Define your upstream services in config/packages/bff_proxy.yaml:
bff_proxy:
upstreams:
api-gateway:
http_client: "@http_client"
request_factory: "@psr17_factory"
stream_factory: "@psr17_factory"
http_foundation_factory: "@psr7_to_httpfoundation_bridge"
Route Proxy Requests
Use the bff_proxy route attribute to proxy requests to an upstream:
// src/Controller/ProxyController.php
use DanielBurger1337\BffProxyBundle\Attribute\BffProxy;
#[Route('/api/{path}', name: 'bff_proxy', methods: ['GET', 'POST'])]
#[BffProxy(upstream: 'api-gateway')]
public function proxy(Request $request, string $path): Response
{
return new Response(); // Handled by the bundle
}
Proxy a frontend request to an internal API while preserving headers:
# config/packages/bff_proxy.yaml
bff_proxy:
upstreams:
internal-api:
http_client: "@http_client"
passthrough_request_headers: ["Authorization", "X-Forwarded-For"]
Define Upstream Services Configure each upstream service with its HTTP client and header passthrough rules:
bff_proxy:
upstreams:
auth-service:
http_client: "@auth_http_client"
passthrough_request_headers: ["Authorization"]
Annotate Routes
Use the #[BffProxy] attribute to mark routes for proxying:
#[Route('/auth/{endpoint}', name: 'auth_proxy')]
#[BffProxy(upstream: 'auth-service')]
public function authProxy(Request $request, string $endpoint): Response
{
return new Response(); // Proxy logic handled by bundle
}
Dynamic Upstream Selection
Use the options_parameter to dynamically select upstreams at runtime:
bff_proxy:
options_parameter: upstream
curl /api/data?upstream=analytics-service
Laravel-Specific Setup
For Laravel, use Symfony’s HTTP client bridge (e.g., symfony/http-client) and configure it in config/services.php:
'http_client' => fn () => new \Symfony\Contracts\HttpClient\HttpClient(),
Middleware Integration Add middleware to modify requests before proxying:
use DanielBurger1337\BffProxyBundle\Event\BffProxyEvent;
public function onProxy(BffProxyEvent $event): void
{
$event->getRequest()->headers->set('X-Custom-Header', 'value');
}
Register it in EventDispatcher:
$dispatcher->addListener(BffProxyEvents::ON_PROXY, [$this, 'onProxy']);
Local Proxy for Development Enable local proxying to bypass upstreams during development:
bff_proxy:
local_proxy: true
Header Passthrough Conflicts
Host or Content-Length may be overwritten by the proxy.passthrough_request_headers and avoid passthrough_request_x_headers: true.CORS and Security Headers
$response->headers->set('Access-Control-Allow-Origin', '*');
Breaking Changes in Minor Versions
0.2.0+ and 0.3.0+ introduced breaking changes (e.g., removed BffProxyVoter).Performance Overhead
Log Proxy Requests
Enable debug mode in config/packages/monolog.yaml to log proxy events:
handlers:
main:
type: stream
path: "%kernel.logs_dir%/%kernel.environment%.log"
level: debug
Inspect Events
Use the BffProxyEvents::ON_PROXY event to debug request/response transformations:
$dispatcher->addListener(BffProxyEvents::ON_PROXY, function (BffProxyEvent $event) {
\Log::debug('Proxy Request:', [
'uri' => $event->getRequest()->getUri(),
'headers' => $event->getRequest()->headers->all(),
]);
});
Custom HTTP Clients Extend the bundle by creating custom HTTP clients for specific upstreams:
upstreams:
custom-service:
http_client: "@custom.http_client"
// src/HttpClient/CustomHttpClient.php
class CustomHttpClient extends \Symfony\Contracts\HttpClient\HttpClient
{
public function request(string $method, string $url, array $options = []): ResponseInterface
{
// Custom logic (e.g., retry, timeout)
return parent::request($method, $url, $options);
}
}
Response Modification
Subscribe to BffProxyEvents::ON_RESPONSE to modify responses:
$dispatcher->addListener(BffProxyEvents::ON_RESPONSE, function (BffProxyEvent $event) {
$response = $event->getResponse();
$response->headers->set('X-Processed-By', 'BFF-Proxy');
});
Dynamic Upstream Routing
Use the options_parameter to route requests dynamically:
bff_proxy:
options_parameter: service
curl /data?service=analytics
Boolean Values in YAML
Use true/false (not yes/no) for boolean flags like local_proxy:
bff_proxy:
local_proxy: false # Disables local proxy
PSR Factories
Ensure your request_factory, stream_factory, and http_foundation_factory are PSR-17 compliant (e.g., nyholm/psr7):
upstreams:
api:
request_factory: "@psr17_factory"
stream_factory: "@psr17_factory"
How can I help you explore Laravel packages today?