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

Laravel Rdap Laravel Package

spatie/laravel-rdap

Query domain registration data in Laravel with RDAP, the structured JSON successor to WHOIS. This package wraps basic RDAP lookups and adds response caching, configurable TLD server caching, and automatic retries with timeouts for unreliable endpoints.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit. spatie/laravel-rdap is a thin, opinionated wrapper around the RDAP protocol (the structured-JSON successor to WHOIS). It exposes a facade (Rdap::domain(), Rdap::ip(), Rdap::dns(), Rdap::domainIsSupported()), returns typed response objects (DomainResponse, IpResponse) with convenience accessors (registrationDate(), expirationDate(), hasStatus(), get() with dot notation, all()), and ships a config file for retry/timeout and TLD-server cache behavior. Architecturally it belongs in the "integration adapter" layer of a Laravel monolith or a small domain-intelligence service — not in a hot request path and not as a system of record. It is a query client, not a data pipeline.

Integration feasibility. Very high on paper: composer require, one vendor:publish, then facade calls. It fits any Laravel 8+–12 codebase (PR #39 added Laravel 12 support; PR #40 fixed a PHP 8.4 deprecation), which matters because it signals the maintainer is keeping pace with the framework. No database migrations, no queue workers, no external services to provision beyond outbound HTTPS. A competent Laravel engineer can produce a working spike in under a day.

Technical risk. The risks are ecosystem and protocol, not code:

  • Adoption signal is weak. 72 stars and 0 dependents means almost no third-party production validation. We would be an early adopter, and early adopters absorb the debugging.
  • Protocol coverage is partial. The README is explicit that not all TLDs are supported (.be is called out as returning false from domainIsSupported). Any product requirement implying "look up any customer domain" is unsupported by this package alone and needs a WHOIS fallback path.
  • Synchronous-only design. Every domain()/ip() call is a blocking HTTP round trip with up to 3 retries × 5s timeout + 1s sleeps — a worst case of ~18s per lookup. There is no batch API, no queue integration, and no async primitive. Bulk enrichment must be built by us on top of it.
  • Reliability is acknowledged, not solved. The package's own README concedes RDAP "seem[s] to be a bit unreliable" and mitigates with blind retries. That is a reasonable client-side posture but it means upstream flakiness is a permanent operating condition, not an edge case.
  • Bus factor / maintenance concentration. Single-vendor (Spatie), effectively one primary author plus community PRs. Most changelog entries are Dependabot bumps; substantive changes are small and infrequent.
  • Documentation inconsistency. The README claims caching of responses out of the box, but the published config only exposes tld_servers_cache. The typo timeoutInSecons in the documented parameter name suggests the README was not validated against the code. Both are yellow flags for a package we'd depend on.

Key questions for the team.

  1. What is the actual product requirement — display-only registrar/expiry info, or automated decisions (renewal reminders, fraud scoring, takedown workflows)? The latter raises accuracy and availability bars considerably.
  2. Does response caching exist beyond the TLD-server list? If not, who owns rate-limit and cache strategy?
  3. What is our fallback for unsupported TLDs — WHOIS library, commercial API (e.g., a registrar/WHOIS vendor), or explicit "not supported" UX?
  4. Do we need IP/ASN lookups (RdapIpV4), or is this domain-only? Scope changes the surface area.
  5. Are we willing to fork/patch if the package stalls? Who owns that?
  6. What is the latency budget for the calling feature, and can lookups move off the request thread?

Integration Approach

Stack fit. Native fit for a standard Laravel stack (Composer, service container, config, facades, Carbon). It requires no infrastructure beyond outbound HTTPS egress to IANA and registry endpoints (data.iana.org, rdap.verisign.com, rdap.arin.net, etc.). If we run behind a locked-down egress proxy or in a VPC with restricted egress, that allowlist becomes a prerequisite ticket — flag it early, it is the most common surprise.

Migration path. There is nothing to migrate from unless we already run raw WHOIS or cURL calls to RDAP endpoints. In that case:

  1. Introduce the package behind an internal interface (DomainLookupService) rather than calling the facade directly in controllers/jobs. This is the single most important decision — it decouples us from a low-dependency package and makes a future swap or fork a one-file change.
  2. Implement the interface with the package as the first adapter; keep the legacy WHOIS path as a second adapter for unsupported TLDs.
  3. Route all callers through the interface, then delete direct protocol code.

Compatibility. Confirm our Laravel and PHP versions against the release line (Laravel 12 / PHP 8.4 fixes are the most recent movement). Pin the version explicitly in composer.json and commit the rdap.php config to version control rather than treating it as a local artifact — the retry defaults (3 × 5s) are product decisions, not library defaults. Note the config exposes a store_name for the TLD cache; if we run multiple app servers, we must set this to a shared store (Redis) or every node will independently fetch and cache the IANA list.

Sequencing.

  • Week 0 — Spike. One engineer, timeboxed: install, publish config, run domain(), ip(), domainIsSupported() against a representative set of our real customer domains (not google.com). Measure supported-TLD ratio and p50/p95 latency. This single experiment resolves the biggest open questions.
  • Week 1 — Decision gate. Go/no-go based on TLD coverage against our actual domain portfolio and whether latency fits the target feature.
  • Week 2 — Adapter + cache. Wrap in the internal service, add our own response cache (TTL aligned to registry update cadence, not to request cadence), configure a shared cache store, add structured logging.
  • Week 3 — Async path. Move any non-interactive lookups into queued jobs with bounded concurrency and per-job timeouts; keep interactive lookups to a single attempt with a short timeout and a graceful "unavailable" state.
  • Week 4 — WHOIS fallback + observability. Add the fallback adapter for unsupported TLDs, dashboards on error rate and latency, and an alert on RdapException volume.
  • Post-launch — Ownership review. Reassess quarterly: is the package still receiving framework-compat updates? If not, we own the fork.

Operational Impact

Maintenance. Low code-maintenance burden, moderate dependency-maintenance burden. The package surface we touch is small and stable (RDAP itself is a settled IETF protocol). The recurring work is: framework/PHP upgrade compatibility (historically handled promptly by the maintainer — Laravel 12 in 1.1.1, PHP 8.4 in 1.1.2), and our own cache/fallback logic. Budget a few hours per quarter for dependency review, plus a defined fallback plan if the project goes quiet. Because we're at 0 dependents, we should assume we're one of very few production users and that bugs we find will be ours to fix or upstream via PR.

Support. No vendor SLA. Support model is: Spatie's GitHub issues, community PRs, MIT license (fork-friendly — this is the meaningful mitigation). Internal ownership should sit with the backend team that owns the calling feature; do not let this become an orphaned integration that nobody can debug. Document the TLD-coverage limitation in the runbook before launch, because "domain lookup returned nothing" will otherwise be triaged as a bug when it is expected behavior for unsupported TLDs.

Scaling. The package itself does not scale — it makes one blocking HTTP call per query. Scaling levers are ours to build:

  • Caching is the dominant lever. Domain registration data changes on the order of months; a multi-hour or daily TTL on our own response cache collapses query volume dramatically. Do not rely on the package's TLD-list cache as a substitute for response caching.
  • Queueing for anything bulk. Never fan out N synchronous lookups in a request or a single job; use per-lookup jobs with rate limiting.
  • Egress politeness. Registry RDAP endpoints are public and generally tolerant, but we are a guest. Unbounded concurrency invites rate limiting or IP blocks. Set a conservative concurrency cap.
  • The one-week TLD-server cache means a single IANA fetch per week per shared cache store — negligible, provided store_name is configured to a shared store.

Failure modes. Enumerate these explicitly in the runbook:

  • RdapRequestTimedOut — upstream slow; surfaces after ~18s of retries with default config. In a request path this is user-visible latency. Mitigation: short timeout + fewer retries for interactive calls, longer for jobs.
  • InvalidRdapResponse — malformed upstream payload. Not retried away; treat as a data-quality signal and log the raw body.
  • null return from domain() — ambiguous by design: it can mean "domain does not exist" or "registry returned nothing." If the product must distinguish these, we need additional logic; this ambiguity is a real UX risk.
  • Unsupported TLD — domainIsSupported() returns false (e.g., .be). Must be a designed state, not an error.
  • IANA list unavailable at cold start — with a shared cache store and weekly TTL, the blast radius is small; on cache flush, expect a brief latency bump.
  • Silent data staleness — if our response cache TTL is too long, expiry-date changes lag. Acceptable for display, potentially not for automated renewal workflows.

Ramp-up. Trivial for anyone who knows Laravel — the facade and response accessors are self-documenting and the README's usage examples are directly runnable. Realistic ramp: half a day to productive, one sprint to own the integration end-to-end including fallbacks and observability. The non-obvious learning is entirely at the protocol edges (TLD coverage, null ambiguity, retry-latency math), not in the package API — which is exactly why the spike in Week 0 should test our real domain portfolio rather than canonical examples. Overall: a low-cost, low-risk, low-ceiling component — adopt behind an internal interface, with eyes open that we are near the front of the adoption curve.

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.
mrnewport/laravel-plaid
mrnewport/laravel-repo
mrnewport/laravel-docsign
mrnewport/laravel-stow
mrnewport/laravel-flow
mrnewport/laravel-priceable
mrnewport/laravel-nestedterms
fredmeng/laravel-apidoc-generator
itstructure/laravel-multilingual-tools
pdustdar/elasticsearch
markupai/php-sdk
rlacerda83/lumem-microservice-shipment
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle
glavweb/extra-bundle
glavweb/api-bundle
glavweb/admin-bundle