openpp/notificationhubs-rest-php
A PHP client for the Azure Notification Hubs REST API, helping Laravel and PHP applications send push notifications and manage registrations or installations through a simple, framework-friendly interface.
Architecture fit
openpp/notificationhubs-rest-php is a thin, framework-agnostic REST client for the Azure Notification Hubs service — it wraps HTTP calls (send, registration/installation management, SAS token generation) and returns decoded responses. It carries no Laravel service provider, facade, config publishing, or queue integration, so it slots in below your application layer rather than beside it. For a Laravel codebase the practical pattern is:
NotificationHubServiceProvider, constructed from config/services.php values (connection_string, hub_name, endpoint).PushGateway) so controllers/jobs never touch the vendor class directly.ShouldQueue), never synchronously in a request cycle — Notification Hubs calls are tens to hundreds of milliseconds and are a classic tail-latency source.The package's lack of Laravel opinions is arguably a feature here: there is very little surface area to conflict with your conventions. The trade-off is that 100% of the Laravel ergonomics are yours to build — budget roughly 1–2 engineer-days for provider, config, interface, DTOs, and a job with retry/backoff.
Integration feasibility
Feasible and low-ceremony. The dependency footprint appears minimal (HTTP client plus JSON), which keeps the Composer graph clean. The real feasibility questions are version-drift questions, not design questions:
composer.json allows PHP 8.1+/8.3 and a current Guzzle (7.x). A wrapper pinned to Guzzle 6 will create a dependency-resolution fight with modern Laravel.Technical risk
This is the dominant concern and it is a maintenance risk, not a functional one.
Mitigations to decide on before adoption:
Authorization: SharedAccessSignature ... header) stays under a day.composer.json and commit the lockfile; do not allow ^ ranges.Key questions for the evaluation spike
Stack
Target a Laravel 10/11 app on PHP 8.2+ with Redis-backed queues and Horizon for visibility. The integration layer you build is small and conventional:
config/services.php → azure.notification_hub.{connection_string, hub_name}, sourced from environment/Key Vault, never committed.App\Push\NotificationHubGateway (interface) with one implementation delegating to the vendor client.App\Jobs\SendPushNotification implementing ShouldQueue, $tries = 3, backoff() returning [10, 60, 300], retryUntil() capped at ~15 minutes.PushResult value object normalizing {accepted, trackingId, correlationId, errorCode} so callers are insulated from the vendor's return shape.notification_id, user_id, platform, tag_expression, http_status, tracking_id. This is what makes NH debuggable later.Migration
If you are currently on a direct-APNs/FCM implementation or an older NH library, migrate behind the interface, not by rewriting call sites:
If this is greenfield, skip straight to the interface + job and treat migration as a non-issue.
Compatibility
The two concrete gates are Composer resolution and payload shape. Run composer require openpp/notificationhubs-rest-php --dry-run on the actual app before any design work; if it drags in an incompatible Guzzle or a conflicting PSR-7 implementation, the evaluation ends there. Second gate: confirm your APNs/FCM credentials are configured on the hub (NH holds the platform credentials, not your app) — a widespread source of confusion that shows up as 401/404 from NH rather than from the package.
Sequencing
Week 1: dependency spike, API-coverage audit, dev NH namespace provisioned, contract tests written. Week 2: provider/config/interface/job, one notification type in production behind a flag, dashboards wired. Week 3–4: registration/installation write path, dual-run comparison, cutover. Budget an explicit fallback decision point at the end of week 1: if the package fails the Installation API, FCM v1, or Composer gates, write the client in-house instead. That decision should be made by the TPM with the tech lead, not deferred.
Support model
Community-only, single maintainer, MIT. There is no vendor to escalate to and no security-response process. Operationally you must own: version pinning, an internal fork or patch branch ready to go, and a documented "if this package breaks, here is the 150-line replacement" note in the runbook. Assign a named owner on the platform team. A dependency with 0 dependents has no crowd to notice breakage for you — your contract tests are the canary.
Failure modes to instrument
201 with a tracking ID even when individual device tokens are dead. HTTP success is not delivery success. You must reconcile via NH per-message feedback / APNs feedback and prune stale installations, or your device registry will slowly rot and delivery rates will drift down unnoticed.correlation_id so retries don't double-notify.wait time > 60s), not just queue depth.Ramp-up
Low for a mid-level engineer: the API surface is small and the integration is thin. Realistically half a day to be productive, with the learning concentrated in Azure Notification Hubs semantics (hub vs. namespace, registrations vs. installations, tag expressions, NH tier quotas) rather than in this package. That knowledge is worth acquiring regardless of whether you keep the library, because it is the part that does not transfer away.
Ongoing cost
Cheap in code, non-trivial in attention. Expect: NH service cost by tier, ongoing stale-installation hygiene, and a quarterly dependency review to check whether the repo has gone quiet. The honest operational posture is "acceptable commodity adapter under an abstraction boundary" — approve it on that basis, reject it as a strategic dependency, and set a review trigger (no upstream commit in 12 months, or any 6-hour-plus outage traced to the wrapper) that forces the in-house swap.
How can I help you explore Laravel packages today?