dmstr/api-configuration-bundle
Installation
composer require dmstr/api-configuration-bundle
Add to config/bundles.php:
return [
// ...
Dmstr\ApiConfigurationBundle\DmstrApiConfigurationBundle::class => ['all' => true],
];
Database Migration
Run migrations to create the api_configuration table:
php bin/console doctrine:migrations:diff
php bin/console doctrine:migrations:migrate
First API Configuration Create via CLI:
php bin/console api-configuration:create --type=stripe --endpoint=https://api.stripe.com
(Follow prompts for credentials—encrypted automatically.)
Basic Usage Fetch a configuration by ID:
use Dmstr\ApiConfigurationBundle\Entity\ApiConfiguration;
use Dmstr\ApiConfigurationBundle\Repository\ApiConfigurationRepository;
$repo = $this->container->get(ApiConfigurationRepository::class);
$config = $repo->find(1); // ID from DB
// Use the adapter (see Implementation Patterns)
Register an Extension
Create a service tagged as api_extension:
# config/services.yaml
services:
App\Api\StripeExtension:
tags: ['api_extension']
Implement ApiExtensionInterface:
use Dmstr\ApiConfigurationBundle\Extension\ApiExtensionInterface;
class StripeExtension implements ApiExtensionInterface {
public function getType(): string { return 'stripe'; }
public function getClient(ApiConfiguration $config): ClientInterface {
return new Client([
'base_uri' => $config->getEndpoint(),
'auth' => [$config->getCredentials()['key'], '']
]);
}
}
Fetch and Use an Adapter
$registry = $this->container->get('api_extension.registry');
$extension = $registry->getExtensionFor($config); // Returns StripeExtension
$client = $extension->getClient($config);
// Use $client to call the API
$response = $client->request('GET', '/v1/charges');
Configure for OAuth
Extend AuthorizableExtensionInterface:
use Dmstr\ApiConfigurationBundle\Extension\AuthorizableExtensionInterface;
class GitHubExtension implements AuthorizableExtensionInterface {
public function getAuthorizeUrl(ApiConfiguration $config): string {
return 'https://github.com/login/oauth/authorize?client_id=' . $config->getCredentials()['client_id'];
}
public function getTokenUrl(): string { return 'https://github.com/login/oauth/access_token'; }
public function getType(): string { return 'github'; }
}
Trigger Authorization
$extension = $registry->getExtensionFor($config);
$authUrl = $extension->getAuthorizeUrl($config);
// Redirect user to $authUrl (handle callback via bundle's OAuth controller)
Handle Callback
Configure routes (see config/routes.yaml in bundle) and implement handleAuthorization() in your extension.
php bin/console api-configuration:health 1 --extension=stripe
php bin/console api-configuration:test-connection 1
Credentials Encryption
Adapter Discovery
api_extension to be discovered.php bin/console debug:container api_extension.registry to verify loaded extensions.OAuth State Management
handleAuthorization().Endpoint Validation
getClient() method:
if (!filter_var($config->getEndpoint(), FILTER_VALIDATE_URL)) {
throw new \InvalidArgumentException('Invalid endpoint URL');
}
Check Logs
Enable debug mode (APP_DEBUG=true) to see OAuth flow logs or adapter loading issues.
Extension Loading Issues Clear the cache if extensions aren’t discovered:
php bin/console cache:clear
Custom Operations
Extend the ApiConfiguration entity to add custom fields (e.g., timeout, retry_policy):
// src/Entity/ApiConfiguration.php
#[ORM\Column(type: 'integer', nullable: true)]
private ?int $timeout = 30;
Update migrations and adapters to use these fields.
Health Check Logic
Override the default health check by implementing HealthCheckableExtensionInterface:
use Dmstr\ApiConfigurationBundle\Extension\HealthCheckableExtensionInterface;
class CustomExtension implements HealthCheckableExtensionInterface {
public function healthCheck(ApiConfiguration $config): bool {
// Custom logic (e.g., call a specific API endpoint)
return $this->getClient($config)->get('/health')->getStatusCode() === 200;
}
}
Bulk Operations
Use Doctrine’s Repository to fetch multiple configs:
$configs = $repo->findBy(['type' => 'stripe']);
foreach ($configs as $config) {
$extension = $registry->getExtensionFor($config);
// Process each
}
Environment-Specific Endpoints
Override the default endpoint in your extension’s getClient():
$endpoint = $config->getEndpoint() ?? config('services.stripe.endpoint');
Disable Encryption
Set dmstr_api_configuration.encrypt_credentials: false in config/packages/dmstr_api_configuration.yaml (not recommended for production).
How can I help you explore Laravel packages today?