sitepark/oparl-client
A PHP client for OParl, the open standard for parliamentary information systems. Query OParl APIs to retrieve bodies, meetings, papers, and agendas through a clean, typed interface that integrates smoothly into Laravel applications.
Architecture fit. sitepark/oparl-php-client is a domain-specific API client for OParl, the German standard for open parliamentary information systems (councils, committees, papers, meetings). It is not a Laravel package in the strict sense — no service provider, no facade, no config publishing — so it sits in the "framework-agnostic PHP library" tier of our dependency graph. That is acceptable but means we own the wiring (container binding, config, caching, HTTP transport) ourselves rather than inheriting Laravel conventions.
The 1.0.0 surface is coherent for a first stable cut: an OParl client, typed object models for OParl object types, list pagination, references, query parameters, and JSON round-tripping (serialize/restore with serializable references). For a TPM this is the correct shape — a read-oriented client that maps a remote standard into typed PHP objects with a serialization boundary suitable for caching or queue payloads.
Integration feasibility. Feasible. It is a plain Composer dependency requiring PHP 8.1, which aligns with modern Laravel baselines. The hard prerequisite is not technical but organisational: a reachable OParl endpoint (typically a municipal or state parliament system) and a business reason to ingest that data. If no such endpoint is in scope, this package has no home in our stack.
Notable integration friction points to plan for:
Http facade. We must confirm and, if needed, build an adapter so we do not end up with two HTTP stacks.Technical risk. Moderate and mostly bounded:
sitepark-becker) and a first stable release. The engineering signals are genuinely good — Psalm-precise types, mutation testing, infection tooling, commit hooks, changelog — which suggests a disciplined maintainer. But bus factor is 1 and production battle-testing is unknown.Key questions. Before committing:
Stack fit. Compatible with our PHP 8.1+ / Laravel baseline. Composer-installable, PSR-friendly, framework-agnostic — which is a mild negative for Laravel ergonomics but a positive for lock-in and testability. It occupies a narrow niche: it is the right tool if and only if we are consuming OParl data. It is not a general HTTP or RPC client and should not be evaluated as one.
Recommended placement: a dedicated Opal/Parliament integration module behind a thin internal interface (e.g. ParliamentDataSource) so the rest of the app never imports the package's types directly. This keeps the vendor surface to one adapter layer and makes the "what if we swap clients" question cheap.
Migration path. There is no prior state — this is a greenfield adoption at 1.0.0, not an upgrade. Two realistic paths:
Because this is 1.0.0, we should pin an exact version in composer.json (e.g. 1.0.0 rather than ^1.0) for the pilot, and only widen to a caret constraint after the first minor release proves the API is stable.
Compatibility. PHP 8.1 is explicitly supported, matching current Laravel LTS requirements. Watch two things: (a) whether the package declares a Laravel version constraint at all — it almost certainly does not, so composer will not warn us on a Laravel major upgrade; (b) the HTTP client dependency, which is the most likely source of version conflicts with our existing stack. Resolve the dependency graph in a throwaway branch before committing.
Sequencing. A pragmatic order:
Maintenance. Low-to-moderate and mostly ours, not theirs. The package itself should be stable post-1.0.0; the maintenance burden is the adapter, the cache strategy, and the retry/budget logic we layer on top. The upstream project shows healthy hygiene — Psalm types, mutation testing, changelog, commit hooks, dev files excluded from the package — which reduces the odds of nasty surprises. Counterweight: a single maintainer, so we should be prepared to fork or vendor the package if it goes quiet. Given the small surface, forking is realistic rather than catastrophic.
Support. Community/open-source with no commercial backing identified. That is acceptable for a read-only data client in a non-critical path, but it means we are our own first line of support. Any OParl-consuming feature we build on this becomes an internal capability we must staff, document, and own — do not frame this as "buy a library, get support".
Scaling. The scaling dimension that matters is not throughput but request amplification. Every list traversal is N pages, and every reference dereference is potentially another request. A naive "load the meeting, load its papers, load each paper" pattern is quadratic-ish over HTTP and will hit municipal endpoints that are not sized for it. Mitigations to build in from the start:
With those in place, scale is bounded by the upstream endpoint, which is the real constraint, not by the client.
Failure modes. Enumerated for the runbook:
Ramp-up. For a Laravel-fluent engineer: 1–2 days to be productive, since the package is small and the model is a straightforward object graph. The real ramp-up cost is OParl domain literacy — understanding Body, Meeting, Paper, AgendaItem, reference semantics, and list pagination — which is 3–5 days of reading the spec and poking a real endpoint. Budget a week for the first engineer to reach confident productivity, and capture that learning in the adapter layer's documentation so the second engineer does not repeat it. The absence of Laravel idioms (no facade, no published config) means onboarding material has to be written by us, not inherited from the package.
Recommendation. Green-light a bounded pilot, not a committed integration. The engineering quality signals are good, the scope is narrow and honest, and the 1.0.0 feature set covers the OParl essentials with evidence of real-world hardening (BOM handling, pagination cycles, mutation-tested edge cases). The blockers to a full commitment are the unanswered questions around reference dereferencing, error semantics, and pagination bounds — all resolvable in a short spike. Pin the version, isolate behind an adapter, enforce our own request and page budgets, and treat parsing tolerance as a resilience feature to be paired with our own validation, not a substitute for it.
How can I help you explore Laravel packages today?