Installation Add the bundle to your project via Composer:
composer require canaltp/navitiaio-api-bundle
Enable the bundle in config/bundles.php:
return [
// ...
CanalTP\NavitiaIoApiBundle\NavitiaIoApiBundle::class => ['all' => true],
];
Configuration
Define your Navitia API credentials in config/packages/navitia_io_api.yaml:
navitia_io_api:
api_key: '%env(NAVITIA_API_KEY)%'
base_uri: '%env(NAVITIA_BASE_URI)%'
timeout: 30
First Use Case
Inject the NavitiaIoApi service in a controller or service:
use CanalTP\NavitiaIoApiBundle\Service\NavitiaIoApi;
class TripController extends AbstractController
{
public function __construct(private NavitiaIoApi $navitiaApi) {}
public function getTripDetails(string $tripId): JsonResponse
{
$trip = $this->navitiaApi->get('/v1/trips/{tripId}', [
'headers' => ['Accept' => 'application/json'],
]);
return $this->json($trip);
}
}
API Requests Use the service for standard HTTP requests with automatic authentication:
$response = $this->navitiaApi->get('/v1/coverage/fr-idf', [
'query' => ['date' => 'today'],
]);
Pagination Handling Iterate over paginated results:
$page = 1;
do {
$results = $this->navitiaApi->get('/v1/stops', [
'query' => ['page' => $page],
]);
// Process $results
$page++;
} while (!empty($results['_links']['next']));
Error Handling Wrap API calls in try-catch blocks:
try {
$data = $this->navitiaApi->post('/v1/stop_areas', ['json' => $stopAreaData]);
} catch (NavitiaIoApiException $e) {
$this->addFlash('error', $e->getMessage());
return $this->redirectToRoute('home');
}
Caching Responses Cache frequent queries (e.g., coverage data):
$cacheKey = 'navitia_coverage_fr-idf';
$coverage = $this->navitiaApi->getCached($cacheKey, '/v1/coverage/fr-idf', 3600);
Hydrator.version query parameter for backward compatibility:
$this->navitiaApi->get('/v1/stop_areas', ['query' => ['version' => 'v1.2']]);
Rate Limiting Navitia Io may throttle requests. Implement exponential backoff:
$this->navitiaApi->setRetryStrategy(new RetryStrategy(3, 100));
Deprecated Endpoints
Monitor Navitia’s API changelog for deprecated routes (e.g., /v0/ → /v1/).
Case Sensitivity
Endpoints like /v1/stop_areas are case-sensitive. Use the exact path from the API docs.
Large Payloads
Avoid sending large JSON payloads in POST/PUT requests. Stream data or chunk uploads.
Enable Verbose Logging Configure Monolog to log API requests:
# config/packages/monolog.yaml
handlers:
navitia:
type: stream
path: "%kernel.logs_dir%/navitia.log"
level: debug
channels: ["navitia_io"]
Then enable channel in NavitiaIoApi:
$this->navitiaApi->setLogger($this->container->get('monolog.logger.navitia'));
Inspect Raw Responses
Use getRawResponse() to debug headers/status codes:
$response = $this->navitiaApi->get('/v1/stop_areas');
$raw = $response->getRawResponse();
Custom HTTP Clients
Replace the default GuzzleHttp\Client by binding a custom client:
# config/services.yaml
services:
CanalTP\NavitiaIoApiBundle\Service\NavitiaIoApi:
arguments:
$client: '@custom.http.client'
Middleware Add request/response middleware:
$this->navitiaApi->getClient()->getEmitter()->addSubscriber(
new AddAuthHeaderMiddleware('X-Custom-Header', 'value')
);
Event Listeners
Subscribe to NavitiaIoApiEvent for pre/post-request logic:
$dispatcher->addListener(NavitiaIoApiEvent::PRE_REQUEST, function (NavitiaIoApiEvent $event) {
$event->setOption('headers', ['X-Request-ID' => uniqid()]);
});
Testing
Mock the NavitiaIoApi service in PHPUnit:
$mockApi = $this->createMock(NavitiaIoApi::class);
$mockApi->method('get')->willReturn(['data' => 'mocked']);
$this->container->set('navitia_io_api', $mockApi);
How can I help you explore Laravel packages today?