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

Ratsit Bundle Laravel Package

jongotlin/ratsit-bundle

A PHP bundle that integrates the Ratsit API for Swedish people and company lookups, letting developers fetch address, age, and contact details directly in their applications. Lightweight and straightforward to configure, though documentation and community adoption are still limited.

View on GitHub
Deep Wiki
Context7

Getting Started

The framing before anything else: jongotlin/ratsit-bundle is a Symfony bundle, not a Laravel package. It exists only to wire the underlying jongotlin/ratsit client (a PHP wrapper around the Ratsit.se Swedish people/company lookup API) into Symfony's DI container via a Bundle subclass and a YAML config tree. Laravel has no bundle concept, no compiler passes, and no config tree — so the bundle will not boot in a Laravel app as shipped. Treat it as reference glue, not a dependency.

Do this instead:

composer require jongotlin/ratsit

Then bind the client yourself in a service provider:

// app/Providers/RatsitServiceProvider.php
public function register(): void
{
    $this->app->singleton(\Jongotlin\Ratsit\Ratsit::class, fn () => new \Jongotlin\Ratsit\Ratsit(
        config('services.ratsit.api_key'),
        // pass the same constructor args the bundle's extension passes;
        // read src/DependencyInjection/ of the bundle to get the exact signature
    ));
}

Put credentials in config/services.php + .env (RATSIT_API_KEY=...), never in source control.

Where to look first:

  1. The underlying jongotlin/ratsit README — the bundle has no documentation of its own worth reading.
  2. The bundle's src/DependencyInjection/ — this is your config blueprint. It tells you exactly which constructor arguments and container parameters are required, which is the one genuinely useful thing the bundle contributes.
  3. composer show --tree jongotlin/ratsit — check whether the "framework-agnostic" core quietly pulls symfony/* transitively before you commit.

First use case: enriching a customer at signup. A user submits a personnummer, you fetch name/address/age to prefill an order. That single call forces you to solve auth, rate limiting, caching, personnummer validation, and GDPR in one pass — so prototype it first even if the eventual feature is something else.

Implementation Patterns

Wrap the client behind your own contract. Never let Jongotlin\Ratsit\Ratsit leak into controllers, models, jobs, or anywhere else. Define a small interface and bind a concrete implementation:

interface PersonLookup
{
    public function findBySsn(Personnummer $ssn): ?PersonData;
}

This gives you a fake for tests, a seam to swap vendors (UC, Creditsafe, Veriff), and a place to hang retries/logging without touching call sites.

Normalise the personnummer at the boundary. Accept YYYYMMDD-XXXX, YYMMDDXXXX, with/without century, and handle samordningsnummer (day + 60). Luhn-check before spending a paid API call on a typo. Make it a value object — it pays for itself the first time a user pastes a number with a stray space or a non-breaking space.

Queue the lookups. Never block a web request on a third-party call. Dispatch LookupPersonJob on a low-concurrency queue so a slow or rate-limited Ratsit API can't take down your signup flow. Return a "we're enriching your profile" state and let the UI reconcile.

Cache deliberately, with a TTL you can defend. Names and addresses change rarely; the API is billed per request. Cache by personnummer for a bounded window (24h–7d typical), tag the entries, and purge on data-subject request. Never cache "not found" for long — a person may have just moved into the country or been registered.

Rate limit client-side before you hit theirs. Ratsit's terms impose request ceilings; wrap the client in Laravel's RateLimiter or a Redis token bucket per API key. Better to queue and back off than to eat a 429 (or worse, a suspension) in production.

Isolate the client behind a resilience layer. Use Laravel's Http::retry() if the underlying client exposes a PSR-18/PSR-17 boundary, or wrap with a decorator that adds retry with jitter, circuit breaking, and structured logging. You own this — the bundle never gave it to you anyway.

Testing pattern:

$this->swap(PersonLookup::class, new FakePersonLookup(...));

Or hit the real client against a recorded HTTP fixture using Http::fake(). Since the underlying client likely uses a standard HTTP client, you can usually intercept it. If not, the decorator seam saves you.

Gotchas and Tips

It is not a Laravel package. The dependency names say "Symfony" — check composer why for symfony/uid, symfony/serializer, symfony/clock, etc. Pulling symfony/* transitively into a Laravel app is survivable but is a maintenance tax and a frequent source of version-pin conflicts with illuminate/*. Resolve this before committing.

Pin to an exact version, not a caret range. Pre-1.0 semver gives no stability promise. Add a lockfile-diff gate in CI. Assume a minor version can change the constructor signature.

Zero stars, zero dependents, single maintainer. No CVE history is not the same as "no vulnerabilities" — it means "never examined." Budget for a fork, a vendored patch policy, and a named internal owner who can read the source. Do not put this on a customer-facing path without a fallback when Ratsit is down.

GDPR is on you, not on the bundle. The bundle provides no Article 6 legal basis, no DPA, no data-residency guarantees. Before you ship a personnummer to a Swedish API you need a documented legal basis, a retention policy, an erasure path (which is why you tag the cache), and a security review of Ratsit the service — independent of this bundle.

Don't put closures in config. If you're tempted to define the client factory inside config/services.php, note php artisan config:cache will break it. Bind in a service provider; keep config values as scalars only.

Octane / queue-worker safety. Long-lived workers cache container state. Register the client as a singleton only if it's stateless; if it holds auth tokens, refresh them, or bind per-request in Octane. Watch worker memory if the client caches responses internally.

Fail closed on enrichment failures, fail open on the user experience. A failed lookup should never block signup — degrade to "complete your address manually" and log the failure with the request ID. A failed identity verification (a different feature) should block. Know which one you're building.

Extension points that are actually worth borrowing from the bundle: the DI extension's constructor signature (your config blueprint), and any typed response DTOs it maps to. Everything else (YAML config, compiler passes) is Symfony-specific and not portable.

When things break at 2 am: you won't find answers on StackOverflow — there is essentially no corpus for this package. Your debugging path is vendor/jongotlin/ratsit/src/, a Log::debug() of the raw HTTP exchange, and the Ratsit API docs. Build that observability in on day one; the bundle gives you none of it.

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.
skyraptor/chatter
edlugz/sasapay
abbasudo/artisan-route
mirvan/ippanel
ignibyte/aic-framework
glavweb/data-schema-bundle
glavweb/datagrid-bundle
tacticmedia/scim-server
uni-method/frame
neika-ai/sdk
adachsoft/php-code-style
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
adachsoft/api-version-bundle
cgv/localized-resource