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

3Scale Ws Api For Php Laravel Package

3scale/3scale_ws_api_for_php

PHP client for the 3scale Web Services API, enabling PHP applications to integrate with 3scale API management. Provides a lightweight wrapper for working with accounts, applications, services, and related API operations through a simple, consistent interface.

View on GitHub
Deep Wiki
Context7

Getting Started

The 3scale Web Service API client is a plain (non-namespaced) PHP library, so wiring it into Laravel takes a couple of extra steps compared to a typical package.

  1. Install / register the classes. The library ships global classes (ThreeScaleClient, ThreeScaleAuthorizeResponse, ThreeScaleReportResponse, ThreeScaleServiceManagementClient, etc.) that are not PSR-4 friendly. If you install it via Composer from a VCS repository, add a classmap autoload entry in your app's composer.json:

    "autoload": {
        "classmap": ["vendor/3scale/3scale_ws_api_for_php/lib"]
    }
    

    Then composer dump-autoload and php artisan optimize:clear.

  2. Configure it. Add credentials to config/services.php and .env (never commit the provider key):

    'threescale' => [
        'provider_key' => env('THREESCALE_PROVIDER_KEY'),
        'host'         => env('THREESCALE_HOST', 'https://su1.3scale.net'),
        'port'         => env('THREESCALE_PORT', 443),
        'protocol'     => env('THREESCALE_PROTOCOL', 'https'),
    ],
    

    v2.7.1 changed the expected host/port shape for the SaaS backend. Set the host with the scheme (https://su1.3scale.net) and port 443. If your .env currently has su1.3scale.net + 80, or a value like su1.3scale.net:80, that is the breaking change to fix before deploying.

  3. Bind it once in a service provider so nothing else in the app touches constructor arguments:

    $this->app->singleton(\ThreeScaleClient::class, fn () => new \ThreeScaleClient(
        config('services.threescale.provider_key'),
        config('services.threescale.host'),
        config('services.threescale.port'),
        config('services.threescale.protocol'),
    ));
    
  4. First use case: gate an API endpoint. Call authorize($appId, $appKey) in a middleware, read isSuccess() / getUsageReports(), and return 403 on DENIED or 429 when a usage limit is exhausted. Verify against a staging 3scale account first — a bad host/port after this release surfaces as a connection error, not a clean API error.

Implementation Patterns

Wrap the client, don't scatter it. The library's classes are global and its responses have inconsistent helper coverage. Build a small ThreeScale service with authorize(), report(), authorizeAndReport() returning your own value objects. This is the single most valuable move: it isolates the classmap/global-namespace weirdness and lets you fake it in tests.

Authorization middleware for API traffic. Resolve the app ID/key from headers (X-App-Id / X-App-Key are the 3scale convention), call authorize, cache the "plan + limits" portion of the result for a short TTL (30–60s) for high-traffic keys, and short-circuit denied requests. Cache the response, not the decision to skip the call entirely — 3scale owns rate-limit accounting.

Report usage asynchronously. report() is a network call; never do it inline in a hot request path. Push each billable event to a queue job, or use terminate() middleware so the response is already flushed. The client accepts an array of transactions, so a scheduled job that flushes a usage_events table every minute in batches of ~20 is the usual pattern — it also gives you retry and replay semantics 3scale won't give you.

Idempotency via transaction_id. Always set a stable transaction ID (e.g. order-1042 or a UUID persisted with the event). On retries after a timeout you'll otherwise double-bill. Store report result rows so a failed batch can be re-sent.

Fail-open vs fail-closed is a deliberate decision. Put it behind a config flag. For metering/reporting, fail-open (log and move on). For authorization on a paid API, decide per-route. Add a circuit breaker (Cache::remember of a "3scale unreachable" flag with a short TTL) so a 3scale outage doesn't add 3× curl timeouts to every request.

Service Management API for provisioning. Use ThreeScaleServiceManagementClient with an access token (a separate credential from the provider key) when a customer signs up in your app: create application, subscribe to a plan, fetch the app key, store it. Treat this like any onboarding side effect — queue it, and make the job idempotent by looking up existing applications first.

Testing. Because the library uses curl directly, Http::fake() will not intercept it — no matter how many times you try. Bind a fake implementation of your wrapper interface in the container and assert on calls; keep one opt-in integration test against a sandbox account.

v2.7.1 specifics. The new client header (tracking the plugin version to the SaaS backend) is automatic — no code change, but it means your traffic is now attributable by version in 3scale's logs, which is genuinely useful when debugging whether an old deploy is still calling out. The host/port change is the part that needs action: update config/services.php, the .env files for every environment, and any hard-coded constructor calls in tests or scripts.

Gotchas and Tips

  • The breaking change is silent until runtime. No exception at boot; you get a curl connect failure or a redirect on the first authorize. Search the codebase for su1.3scale.net, :80, and '80' before deploying 2.7.1, including Docker/CI env files and Laravel Forge/Envoyer environment variables.
  • TLS after switching to 443. If your servers never made outbound HTTPS calls from PHP, curl's CA bundle may be missing or stale. Symptom: SSL certificate problem: unable to get local issuer certificate. Fix curl.cainfo in php.ini or set it explicitly. Also confirm egress on 443 in security groups/firewalls — 80 may be open where 443 isn't.
  • Config caching. php artisan config:cache bakes the host/port in. After changing .env, always php artisan config:clear locally; on deploy, ensure the cache rebuild happens after the new files land.
  • Global namespace, no PSR-4. You can use \ThreeScaleClient; at the top of a file, but there's no namespace to distinguish it. If another dependency defines ThreeScaleResponse, you'll get a fatal class collision. Keep all usage inside your wrapper service so a future fork/replacement is a one-file change.
  • isSuccess() is not optional. The client returns response objects for both transport-level and API-level failures and does not throw in most paths. Every call site must check isSuccess() and branch on ThreeScaleResponse status constants; otherwise a failed report looks like a success.
  • PHP 8.x compatibility. This is a legacy, untyped codebase; expect dynamic-property deprecation notices on 8.2+ and a no-op curl_close(). Run your test suite with deprecations promoted to errors once to see whether anything in your own glue code is at fault before blaming the library.
  • No built-in timeouts you'd want. Set curl connect/read timeouts in your wrapper (or subclass and override the request method) — defaults can hang a worker for far longer than a request budget allows.
  • Never log the provider key. Exception messages from the client can include the request URL; scrub credentials in your exception handler. The version header added in 2.7.1 is safe to log and is a handy way to confirm which release a given container is actually running.
  • Extension points: your wrapper interface (swap for a mock or a future API client), the container binding (different credentials per environment or per tenant), and a queued report job with retry/backoff — that's where the real durability lives. Treat the vendor library as a thin transport and keep all policy in your own code.
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.
elmogy/larafast
xeviant/laravel-paystack
gorilladash/laravel-website-sdk
martialbe/flysystem-oss
chondal/3312client
jeroen-g/flickr
opscale-co/nova-genbi
itsjustvita/laravel-retention
tequilarapido/trackit
gregsphotography/site-builder-filament
cabaoctavio/laravel-query-log
gregsphotography/site-builder-components
io-digital/clickatell
snowsoft/laravel-admin
oxygen/auth
relicsoftware/barakah-payment-gateway
tobya/work-with-composer
equipc/laravel-email-validator
equipc/laravel-email-database-log
adedsec/nova-translated-labels