Install the Bundle Add the package via Composer:
composer require axelero/mono-bundle
Enable the bundle in config/bundles.php:
return [
// ...
Axelero\MonoBundle\AxeleroMonoBundle::class => ['all' => true],
];
Configure API Credentials Publish the default configuration:
php bin/console config:dump-reference AxeleroMonoBundle
Update config/packages/axelero_mono.yaml with your Mnosolutions API credentials:
axelero_mono:
api_key: "%env(AXELERO_MONO_API_KEY)%"
base_uri: "https://api.mnosolutions.com/v1"
First API Call Inject the client service into a controller or service:
use Axelero\MonoBundle\Service\MonoClient;
class MyController extends AbstractController
{
public function __construct(private MonoClient $monoClient) {}
public function index()
{
$response = $this->monoClient->get('/endpoint');
return $this->json($response);
}
}
Check Documentation Review the bundle’s documentation for endpoint-specific examples and response structures.
RESTful API Calls
Use the MonoClient service for standard HTTP methods:
$this->monoClient->get('/users');
$this->monoClient->post('/users', ['name' => 'John']);
$this->monoClient->put('/users/1', ['name' => 'Updated']);
$this->monoClient->delete('/users/1');
Handling Responses Responses are typically decoded JSON. Use helper methods if provided:
$data = $this->monoClient->get('/users')->getData();
$status = $this->monoClient->get('/users')->getStatusCode();
Error Handling Wrap API calls in try-catch blocks for Guzzle exceptions:
try {
$response = $this->monoClient->get('/users');
} catch (\GuzzleHttp\Exception\RequestException $e) {
$this->addFlash('error', 'API request failed: ' . $e->getMessage());
}
Authentication
The bundle likely handles API key authentication via the api_key config. Avoid hardcoding keys in services.
Pagination
If the API supports pagination, implement logic to handle next_page or limit/offset parameters:
$this->monoClient->get('/users', ['limit' => 50, 'offset' => 0]);
Webhook Listeners (if applicable) If the API supports webhooks, create a Symfony event subscriber or command to process incoming payloads:
use Symfony\Component\HttpKernel\Event\RequestEvent;
class MonoWebhookSubscriber implements EventSubscriber
{
public function onKernelRequest(RequestEvent $event)
{
if ($event->isMainRequest() && $event->getRequest()->getPathInfo() === '/mono-webhook') {
$payload = json_decode($event->getRequest()->getContent(), true);
// Process payload...
}
}
}
Dependency Injection
Prefer injecting MonoClient over instantiating it directly for better testability and configuration management.
Caching Responses
Cache frequent API calls using Symfony’s cache system or a library like symfony/cache:
$cache = $this->container->get('mono.cache');
$cachedData = $cache->get('mono_users', function() use ($client) {
return $client->get('/users')->getData();
});
Logging Log API requests/responses for debugging:
$this->monoClient->get('/users', [
'on_stats' => function ($stats) {
$this->logger->info('API Request Stats', ['stats' => $stats]);
}
]);
Testing
Mock the MonoClient in PHPUnit tests:
$this->mockBuilder->get(MonoClient::class)
->willReturn($this->createMock(MonoClient::class));
Deprecated Symfony Version The bundle requires Symfony 2.3, which is end-of-life (released in 2013). Ensure your project can safely use this version or check for a maintained fork.
Guzzle Version Mismatch
The bundle requires Guzzle 6.x, but Symfony 2.3 may pull an older version. Pin Guzzle explicitly in composer.json:
"require": {
"guzzlehttp/guzzle": "^6.0"
}
No Modern PHP Support The minimum PHP version is 5.3.8, which lacks modern features (e.g., typed properties, arrow functions). Refactor or upgrade if possible.
Undocumented Endpoints
The README lacks examples for specific API endpoints. Reverse-engineer the API using tools like Postman or inspect the bundle’s source (Service/MonoClient.php).
No Rate Limiting
The bundle doesn’t include built-in rate limiting. Implement a decorator or use a middleware like GuzzleHttp\Middleware\RetryMiddleware.
No Event Dispatching If you need to trigger events (e.g., on successful API calls), wrap the client calls manually or extend the bundle.
Enable Guzzle Debugging Add a debug handler to log raw requests/responses:
$this->monoClient->setDebug(true);
// Or configure in services.yaml:
services:
Axelero\MonoBundle\Service\MonoClient:
calls:
- [setDebug, [true]]
Check HTTP Status Codes
Always verify $response->getStatusCode() for non-2xx responses. Example:
if ($response->getStatusCode() === 401) {
throw new \RuntimeException('Unauthorized: Invalid API key');
}
Validate API Responses Use Symfony’s validator to validate responses:
use Symfony\Component\Validator\Validator\ValidatorInterface;
$data = $response->getData();
$errors = $this->validator->validate($data);
if (count($errors) > 0) {
// Handle validation errors
}
Timeouts Configure timeouts in the client:
$this->monoClient->setTimeout(30); // 30 seconds
Custom HTTP Client
Extend MonoClient to add middleware or modify requests:
class CustomMonoClient extends MonoClient
{
public function __construct(GuzzleClient $client, array $config)
{
parent::__construct($client, $config);
$this->client->getEmitter()->attach(
new \Axelero\MonoBundle\Middleware\CustomMiddleware()
);
}
}
Add New Endpoints Dynamically register endpoints if the bundle lacks them:
$this->monoClient->addEndpoint('custom', '/custom-path');
Override Configuration Use Symfony’s parameter system to override defaults:
# config/packages/axelero_mono.yaml
axelero_mono:
api_key: "%env(AXELERO_MONO_API_KEY)%"
base_uri: "%env(AXELERO_MONO_BASE_URI)%"
Add Response Transformers Decorate the client to transform responses:
$this->monoClient->setResponseTransformer(function ($response) {
return json_decode($response, true);
});
Webhook Validation
If using webhooks, validate payloads with a library like league/omnipay or a custom service:
use Axelero\MonoBundle\Validator\WebhookValidator;
$validator = new WebhookValidator();
if (!$validator->validate($payload, $signature)) {
throw new \RuntimeException('Invalid webhook signature');
}
How can I help you explore Laravel packages today?