Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Navitia Bundle Laravel Package

canaltp/navitia-bundle

Symfony bundle that integrates the Navitia API into your application, providing services and configuration to query public transport journey planning, schedules, and network data from Navitia coverage.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit — poor, and the framing is wrong. canaltp/navitia-bundle is a Symfony bundle, not a Laravel package. Its integration surface is Symfony's bundle/DI machinery: a Bundle subclass registered in config/bundles.php (or AppKernel), a DependencyInjection/*Extension that loads service definitions, and a Configuration tree that maps YAML config into constructor arguments for the Navitia API client. Laravel has no analogue for any of that — service providers, the config/ repository, and the container's autowiring are structurally different. Bundles are not portable to Laravel; only the code they wire together is.

What is potentially reusable is the underlying concern: an HTTP client for the Navitia journey-planning API (coverage-scoped endpoints for journeys, places, stop areas, departures, route schedules, isochrones). That logic is typically a thin Guzzle wrapper plus DTOs — which we would reimplement in a Laravel service provider in well under a day. The bundle adds configuration ergonomics, not capability.

Integration feasibility — not feasible as a dependency. Three blockers, in order of severity:

  1. Bootstrap mismatch. Nothing in Laravel will ever call the bundle's build(), boot(), or DI extension. Even if installed, it is inert dead weight.
  2. Composer resolution failure. Laravel 10/11 pins symfony/console, symfony/http-foundation, symfony/routing, symfony/process, etc. to the 6.x/7.x line. A bundle of this vintage will constrain symfony/framework-bundle and/or symfony/http-kernel to 2.8/3.x and PHP to ^5.6|^7.0. composer require will fail outright, and symfony/framework-bundle would drag an entire parallel framework into vendor/ regardless. Verify with composer why-not laravel/framework canaltp/navitia-bundle before spending further time.
  3. Signal quality. Score 0, no stars recorded, 0 dependents, no description beyond "Symfony NavitiaBundle." CanalTP was absorbed into Kisio/Hove and Navitia's stewardship moved to navitia.io. This is an abandoned wrapper around an API that has since evolved. Treat the metadata as conclusive rather than as a gap to be investigated.

Technical risk — high if adopted, low if used as reference. Adopting it means an unpatchable transitive dependency (no maintainer, no CVE response path) sitting in a PHP application we are accountable for. Reading it as documentation is nearly free.

The domain risk is separate and survives reimplementation: Navitia is an external SaaS with per-token quotas and coverage-scoped data. Journey planning is a hard real-time dependency — p95 latency hundreds of milliseconds to a geographically distant endpoint, 404s for unknown/discontinued coverage IDs, and JSON shape drift across API versions.

Key questions

  • Is the requirement "call the Navitia API," or "replicate a specific Symfony app's transit feature"? If the latter, what exactly did the bundle wire up?
  • SaaS (navitia.io, token + quota) or self-hosted Navitia? Self-hosting is a multi-service deployment with GTFS ingestion and PostgreSQL — an infrastructure programme, not a library choice.
  • Which endpoints and which coverages are in scope? That determines whether a 150-line client suffices or a DTO layer is warranted.
  • Is there an existing, maintained PHP client for Navitia we can depend on instead of a bundle?
  • What is the acceptable p95 for a journey query, and is there a cacheable read path (places, stop areas, schedules) versus an inherently real-time one (journeys, departures)?
  • Does the product tolerate transit data being unavailable, and what should it render when it is?

Verdict: do not install. Use the bundle's source as a specification for endpoint shapes and parameter names, and implement a first-party Laravel integration.

Integration Approach

Stack fit — reimplement, don't bridge. Laravel's Http client (Guzzle underneath) covers everything the bundle's transport layer does. The idiomatic shape is:

  • config/navitia.php — base URL, token, default coverage, timeout, retry policy.
  • A NavitiaClient class taking those values via constructor injection.
  • A NavitiaServiceProvider registering it as a singleton and publishing the config.
  • A thin Navitia facade for ergonomics, plus a handful of typed DTOs (Journey, Section, Place, Departure) only for the fields we actually render.
  • An Exception hierarchy mapping HTTP status → domain error (CoverageNotFound, QuotaExceeded, UpstreamUnavailable).

This is roughly a day of work and yields code we own, test with Http::fake(), and can patch.

Migration path. There is no live integration to migrate from — nothing depends on this bundle. If we are porting behaviour from an existing Symfony service, the sequence is: (1) inventory the bundle's configured parameters and the call sites that consume its services; (2) pin the Navitia API version the legacy app was calling; (3) reimplement calls against that version; (4) run both against a fixed set of recorded fixtures and diff the DTOs; (5) cut over behind a feature flag.

Compatibility. Requirements to validate before writing code: PHP version supported by the Navitia API's JSON contract (not a concern), TLS and outbound egress from the Laravel host to the Navitia endpoint, token issuance and rotation process, and whether the client must honour a specific Accept/version header. None of these are inherited from the bundle — they are ours to establish.

Sequencing

  1. composer why-not sanity check to formally close out the bundle option (30 min, produces an artefact for the decision log).
  2. Confirm topology (SaaS vs self-hosted) and obtain a token and a coverage ID.
  3. Spike: one journey query and one places query through the Laravel HTTP client, measured for latency, with fixtures recorded.
  4. Build the provider, config, client, and exception mapping with Http::fake() tests.
  5. Add caching for the cacheable read paths and a retry/timeout policy.
  6. Integrate into the consuming feature behind a flag.
  7. Document the token rotation and coverage-ID ownership.

Operational Impact

Maintenance — favourable, because nothing is inherited. We own ~300 lines instead of depending on an unmaintained bundle. The maintenance burden shifts from "track a dead package's compatibility with future Laravel/Symfony releases" to "track the Navitia API's changelog," which we would have to do anyway. The bundle offered no protection against that and would have actively obstructed it by pinning stale Symfony components. Budget a recurring line item for API version review, and a fixture-refresh job so contract drift surfaces in CI rather than production.

Support — no upstream. Zero dependents and no maintainer means no issue tracker to escalate to, no security advisories, no fix for a PHP 8.x incompatibility. If we had adopted it, the only exit would be a fork — which is a reimplementation with extra steps and a worse starting point. On the Navitia side, support depends on the chosen topology: navitia.io SaaS has a commercial relationship and a quota policy to negotiate; self-hosted Navitia means we are the operator, with no vendor to call.

Scaling. The integration is a thin HTTP client, so scaling is dominated by the upstream. Two levers: (1) caching — places, stop areas, route schedules, and coverage metadata are near-static and should be cached aggressively with a long TTL; journeys and departures are real-time and should not be cached beyond a few seconds, if at all. (2) Graceful degradation — a circuit breaker around the client so a slow Navitia endpoint doesn't consume the PHP-FPM worker pool. Watch the SaaS quota: journey planning is the expensive call, and a retry storm can exhaust a monthly quota in minutes. Cap retries, jitter backoff, and instrument quota consumption as a first-class metric with an alert at 70% of plan.

Failure modes

  • Token expired/rotated → 401 on every call. Needs a distinct exception and an alert, not a generic 500.
  • Quota exhausted → 429 or a Navitia-specific rejection. Must degrade to a "transit unavailable" UI state, not an error page.
  • Unknown coverage ID → 404 with a body that looks superficially like a legitimate empty result. Distinguish "no route found" from "coverage does not exist"; the former is a valid answer, the latter is a config bug.
  • Upstream latency spike → request pile-up. Mitigate with short connect/read timeouts (2s/5s), a circuit breaker, and a hard cap on retries.
  • JSON contract drift → silent null fields and blank UI rather than an exception. Guard with schema-validated DTO hydration and a fixture-based contract test.
  • Self-hosted Navitia only: data staleness after a failed GTFS ingestion, and a much larger blast radius — the transit data pipeline becomes our on-call responsibility.
  • Silent quality regression — the least obvious one. Journey results change as upstream routing data changes. Record fixtures and diff them on a schedule; otherwise a routing-quality change looks identical to a bug in our code.

Ramp-up. Low for the recommended path: a mid-level Laravel engineer unfamiliar with transit data can ship the client, config, tests, and caching in one to two days, and Navitia's REST/JSON surface is self-documenting via its OpenAPI spec. The bundle's source is useful here purely as a worked example of parameter names and endpoint construction — an afternoon of reading, not a dependency. Ramp-up on the domain is the real cost: understanding coverage scoping, journey section types, and the difference between scheduled and real-time data takes considerably longer than the code.

If self-hosted Navitia is chosen, discard the above estimate entirely — that is a data-platform project spanning infrastructure, ingestion, and ongoing operations, and it should be scoped and staffed as such rather than as an integration task.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
tequilarapido/trackit
gregsphotography/site-builder-filament
cabaoctavio/laravel-query-log
gregsphotography/site-builder-components
io-digital/clickatell
snowsoft/laravel-admin
oxygen/auth
relicsoftware/barakah-payment-gateway
tobya/work-with-composer
equipc/laravel-email-validator
equipc/laravel-email-database-log
adedsec/nova-translated-labels
wazza/laravel-db-encryption
hokny/laravel-generator
vonsogt/backup
jengo/queues
jeremykenedy/laravel-observability
coleus/frame
thtg88/journalism
filagora/filagora-ai-forums