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

Sdk Kernel Laravel Package

wxm/sdk-kernel

wxm/sdk-kernel is a lightweight foundation for building Laravel and PHP SDKs, offering shared contracts, configuration, service-provider bootstrapping, and a thin HTTP layer so client packages stay consistent, testable, and easy to integrate.

View on GitHub
Deep Wiki
Context7

Getting Started

composer require wxm/sdk-kernel

Start by reading four files in src/, in this order:

  1. Client.php — the abstract base you extend; holds config, service resolution, and the magic accessors.
  2. Config.php — the array-backed config object with accessor semantics.
  3. ServiceProvider.php — the contract for registering a service against a client.
  4. Exceptions/ — the failure modes the kernel throws (InvalidConfigException and friends).

Then look at a real downstream consumer (e.g. wxm/wechat-sdk) — that is the intended shape of the package and the fastest way to see the kernel in situ.

Minimal first use case — wrap a small HTTP API:

use Wxm\SdkKernel\Client;

class AcmeClient extends Client
{
    protected $providers = [
        'user'    => \Acme\Providers\UserProvider::class,
        'invoice' => \Acme\Providers\InvoiceProvider::class,
    ];
}

$client = new AcmeClient([
    'api_key' => getenv('ACME_KEY'),
    'base_uri' => 'https://api.acme.test',
]);

$client->user->find(42);      // lazily resolves the user service
$client->invoice->list();     // lazily resolves the invoice service

The kernel is deliberately thin: it gives you a config container, lazy service resolution and a uniform client->service->method() surface. You bring the HTTP transport and the service classes.

Implementation Patterns

Provider-per-resource. Map a short name to a provider class in $providers. Every endpoint group (users, orders, webhooks) gets its own service class and its own provider, so the client stays a registry rather than a god object:

protected $providers = [
    'user'    => UserProvider::class,
    'order'   => OrderProvider::class,
    'webhook' => WebhookProvider::class,
];

Constructor override for defaults. Merge caller config over your defaults before handing it to the parent, so incomplete new AcmeClient([]) still works against a sane base URI:

public function __construct(array $config = [])
{
    parent::__construct(array_merge([
        'base_uri' => 'https://api.acme.test',
        'timeout'  => 10,
    ], $config));
}

Config as the seam. Never read getenv() or globals inside a service; read $this->client->getConfig('api_key') instead. That keeps every service testable by constructing a client with a fixture array.

Thin services, fat providers. Put wiring (transport, auth headers, retry policy) in the provider and keep the service a list of endpoint methods that take scalars/arrays and return arrays. This is what makes the kernel pleasant day-to-day: $client->order->cancel($id) reads like the API doc.

Integration with Laravel. Register the client as a singleton in a service provider and publish a config file:

$this->app->singleton(AcmeClient::class, fn ($app) =>
    new AcmeClient($app['config']->get('services.acme'))
);

Resolve by type-hint in controllers/jobs. Do not new the client per request — you lose the shared service instances and re-run config merging each time.

Testing. Because providers are just classes, swap the transport in the config array ('http_client' => $mockPsr18Client) and assert against the kernel-level API rather than against Guzzle internals. For pure unit tests, subclass the client with a stub provider that returns fixed payloads.

Multi-tenant / multi-credential. Instantiate more than one client — one per tenant — rather than mutating config at runtime. The kernel does not reload config on setConfig, and providers may have cached derived state.

Gotchas and Tips

  • It is a kernel, not a framework. No HTTP layer, no retries, no logging, no serialization. Expect to write or install all of it. Plan for Guzzle or any PSR-18 client and keep it injectable via config.
  • Zero stars / zero dependents is a signal about bus factor, not quality. The package is the author's internal foundation for the wxm/* SDK family. Pin an exact version in composer.json and vendor-lock; do not float ^1.0 on a package that can rewrite a method signature in a patch release.
  • Services are resolved lazily by name. A typo in $providers (or in $client->usr->...) fails at call time, not at boot. Add a smoke test that touches every registered service so a broken provider is caught in CI, not in production.
  • Service instances are memoised. Repeated $client->user calls return the same object. Any state you stash on a service (last request id, pagination cursor) leaks across calls. Keep services stateless or expose an explicit reset().
  • Magic access breaks static analysis. __call/__get mean PHPStan and IDEs cannot see $client->user->find(). Mitigate with @property docblocks on the client class, or add explicit typed getters for the services you call most.
  • Config is array-shaped, so nested keys bite. Decide early whether you support dot notation and use it consistently; mixing config('a.b') and config('a')['b'] across services is the most common source of silent nulls.
  • Errors surface as kernel exceptions, not HTTP exceptions. Wrap provider construction in try/catch around the kernel's exception namespace, then re-throw your own domain exception so callers are not coupled to Wxm\SdkKernel\.
  • Debugging tip. When a service "cannot be found", dump array_keys($client->getProviders()) and the resolved class name before the throw — nine times out of ten it is a namespace mismatch from PSR-4 autoloading (src/Providers vs src/ServiceProvider).
  • Extension points worth using: override the service-resolution method in your client to inject a shared transport and logger into every service; implement a base provider that all your providers extend, so auth headers and error mapping live in one place rather than N; override config accessors if you need env-var fallbacks.
  • Compatibility. It targets modern PHP but nothing exotic; if you need PHP 7.0 or below, or you want attributes/enums in your service classes, you are on your own. Check the composer.json require block before planning your own PHP floor.
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.
diephp/sequences
users-au/socialite-provider
twidpay/twid-logger
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