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

Client Bundle Laravel Package

userbase/client-bundle

Symfony bundle integrating the Userbase PHP client. Register and configure the client through bundle configuration, then inject it as a service to add user authentication, sessions, and encrypted per-user data storage to your Symfony application with minimal setup.

View on GitHub
Deep Wiki
Context7

Getting Started

Start by installing the bundle and inspecting exactly what it registers, because there is effectively no public documentation or community footprint to lean on.

composer require userbase/client-bundle

On a modern Symfony app, Flex will usually register the bundle automatically. If not, add it to config/bundles.php:

return [
    // ...
    Userbase\ClientBundle\UserbaseClientBundle::class => ['all' => true],
];

Then create a config file. The exact root key is defined by the bundle's DependencyInjection/Configuration.php, so confirm it before guessing — it is typically userbase_client (or userbase). A config that mirrors the usual client-service shape looks like:

# config/packages/userbase_client.yaml
userbase_client:
    base_uri: '%env(USERBASE_BASE_URI)%'
    api_key: '%env(USERBASE_API_KEY)%'
    timeout: 5
USERBASE_BASE_URI=https://userbase.example.com
USERBASE_API_KEY=change-me

Where to look first (in this order):

  1. README.md — even thin bundles usually show the service ID and a usage snippet.
  2. src/DependencyInjection/Configuration.php — the authoritative list of config keys and defaults.
  3. src/Resources/config/services.{yaml,xml} — the actual service IDs, class names, and whether they are public.
  4. src/ client/service classes — the public methods you can call and the DTOs/arrays they return.

First use case: fetch an identity from UserBase and render it. Wire the client into a controller via constructor injection (use the class name from services.yaml, not a string service ID):

public function __construct(private UserbaseClient $client) {}

#[Route('/me', name: 'me')]
public function me(): Response
{
    $user = $this->client->getUser($this->getUser()->getUserIdentifier());

    return $this->render('me.html.twig', ['user' => $user]);
}

Verify the wiring before writing more code:

bin/console debug:config userbase_client   # confirm keys are loaded
bin/console debug:container --show-private | grep -i userbase

Implementation Patterns

Wrap the client in an application-level adapter. Treat the bundle's client as an infrastructure detail. Define your own interface (App\Userbase\UserDirectory) and implement it with the bundle service. When the bundle's API changes — likely, given its maturity — you only touch one class.

final class UserbaseDirectory implements UserDirectory
{
    public function __construct(private UserbaseClient $client) {}

    public function find(string $id): ?User
    {
        try {
            return $this->client->getUser($id);
        } catch (NotFoundHttpException) {
            return null;
        }
    }
}

Prefer constructor injection and autowiring aliases. If the bundle registers multiple services (a client, a factory, a token store), bind interfaces in config/services.yaml:

services:
    UserbaseClient: '@userbase.client'

Cache reads aggressively. A remote identity service is a latency and availability dependency. Wrap read calls in Symfony Cache and invalidate on write:

return $this->cache->get('ub.user.'.$id, function (ItemInterface $item) use ($id) {
    $item->expiresAfter(300);

    return $this->client->getUser($id);
});

Handle writes as explicit, idempotent operations. If the bundle exposes create/update/delete, put them behind your adapter and log the request payload. Remote writes without local audit trails are painful to debug later.

Integrate with Symfony Security via a custom user provider. If the bundle does not ship a provider, write one that delegates to your adapter. Keep the API call out of the hot path by caching the resolved user in the token/session:

public function loadUserByIdentifier(string $identifier): UserInterface
{
    $remote = $this->directory->find($identifier);
    if (!$remote) {
        throw new UserNotFoundException();
    }

    return (new SecurityUser($remote->id))->setRoles($remote->roles);
}

Use Symfony HttpClient features rather than bolting them on. If the bundle lets you inject an HttpClientInterface, supply a scoped client with retry and timeout configured:

framework:
    http_client:
        scoped_clients:
            userbase.client:
                base_uri: '%env(USERBASE_BASE_URI)%'
                timeout: 5
                retry_failed:
                    max_retries: 2

Add a console command for sync and smoke tests. A userbase:ping or userbase:sync command gives you a fast feedback loop that does not require booting a full HTTP request, and it doubles as a deployment health check.

Test with MockHttpClient. Because the bundle sits on top of HttpClient, you can assert outgoing requests and simulate error paths without hitting a real service — far better than mocking the bundle's concrete client class.

Gotchas and Tips

  • Assume no upstream support. With zero stars and no dependents, there is no Stack Overflow corpus, no recent issue triage, and no guarantee of Symfony-version compatibility. Pin the version ("userbase/client-bundle": "1.0.*" or a commit hash) and read the source before upgrading.
  • Confirm the config root key before writing YAML. A wrong root key is silently ignored by Symfony's config loader; the client then boots with defaults and fails later with a confusing connection error. Run debug:config after every config change.
  • Private services break $container->get(). If you are porting old code, use debug:container to check visibility and prefer rewriting the call site to constructor injection rather than adding public: true.
  • Watch environment variable resolution. If the bundle reads %userbase.api_key% style parameters rather than %env(...)%, env vars may not be picked up in cache:warmup/prod. Check whether the parameter or the env var is authoritative.
  • Set timeouts explicitly. Bundles that build their own HttpClient often inherit a null timeout. One slow upstream call will hang PHP-FPM workers. Override with a scoped client or the bundle's timeout config if it exists.
  • Serialization is usually the weak point. The client probably returns arrays or a loose DTO. Normalize at your adapter boundary (map to your own value objects) so that a null field or a changed key does not leak into templates.
  • Beware N+1 remote calls. A loop over user IDs that calls the client per ID is the classic failure mode. Look for a batch/list endpoint in the client first; otherwise implement chunked fetching with caching.
  • Debugging workflow: debug:container --tag=... | grep userbase, then check var/log/dev.log for the bundle's channel. Add a Monolog channel for the client namespace and log request IDs if the service returns them.
  • Extension points to reach for before forking: decorate the client service (decorates: userbase.client), override bundle templates under templates/bundles/, and use a CompilerPass to swap the HTTP client. Forking a 0-star bundle should be the last resort — vendor the one or two classes you need instead.
  • Authentication caching is critical. Without it, every request hits UserBase to validate the user, multiplying latency and coupling your app's availability to theirs. Cache the resolved user for the token lifetime and refresh on a schedule.
  • Document your assumptions in the repo. Because the bundle changes without notice, leave a short docs/userbase.md recording the pinned version, the endpoints used, and the config keys — future you will not remember which fields the API returned.
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.
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
robertmarney/lara-hierarchial-collections
simonschaufi/rule-doc-generator
emissaoja/emissaoja
blackbricksoftware/gravityforms-civicrm-form-processor
al-rahabi/fancy-crud
jinas/dhivatar-component
mltstephane/laravel-quality
bernskiold/laravel-talentlms
bernskioldmedia/laravel-form-architect