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

Cuzzle Laravel Package

octoper/cuzzle

Cuzzle is a Laravel-friendly cURL wrapper that simplifies HTTP requests with a clean, fluent API. Send GET, POST, and other requests, manage headers and options, and handle responses without boilerplate—ideal for quick API integrations.

View on GitHub
Deep Wiki
Context7

Getting Started

Cuzzle solves one narrow, high-value problem: turning a request object you already have into a copy-pasteable curl string. Treat it as a debugging/logging utility, not an HTTP abstraction.

Install and locate the entry point

composer require octoper/cuzzle

The package is Laravel-friendly but framework-agnostic. On Laravel 5.5+ the service provider/facade should be auto-discovered; if Cuzzle isn't resolvable, register the provider and alias manually in config/app.php. Look at vendor/octoper/cuzzle/src/ first — the public surface is small (a Cuzzle facade/class plus a formatter), and the exact conversion method name (fromRequest(), toCurl(), or similar) is worth confirming in one glance rather than guessing. The core usage is:

use Octoper\Cuzzle\Cuzzle;

$request = new \GuzzleHttp\Psr7\Request(
    'POST',
    'https://api.example.com/orders?expand=items',
    ['Authorization' => 'Bearer '.$token, 'Content-Type' => 'application/json'],
    json_encode(['sku' => 'ABC-1', 'qty' => 2])
);

echo Cuzzle::fromRequest($request); // curl -X POST ... 'https://api.example.com/orders?expand=items' ...

First use case: reproduce a failing outbound call

The highest-return first step is a Guzzle middleware or a Laravel beforeSending hook that dumps the curl command whenever an outbound API call fails. In a Laravel client class:

$response = Http::withToken($token)
    ->beforeSending(function ($request, $options) {
        // $request is a PSR-7 request
        logger()->debug('curl', ['cmd' => (string) Cuzzle::fromRequest($request)]);
    })
    ->post('https://api.example.com/orders', $payload);

Then take the log line, paste it into a terminal, add -v, and diff Guzzle's behaviour against the raw call. That loop — log → paste → compare — is where the package earns its keep.

Implementation Patterns

1. Opt-in debugging via config/env. Never format requests unconditionally in production. Gate it behind config('app.debug'), app()->isLocal(), or a dedicated services.cuzzle.enabled flag, plus a sampling switch for high-traffic endpoints.

2. Capture on failure only. Logging every outgoing request creates noise and leaks credentials. Wrap in try/catch or inspect status codes and emit the curl string only for 4xx/5xx:

try {
    $response = Http::withToken($token)->post($url, $payload);
    $response->throw();
} catch (\Throwable $e) {
    logger()->error('Outbound API failed', [
        'curl' => (string) Cuzzle::fromRequest($request),
        'status' => optional($e->response)->status(),
    ]);
    throw $e;
}

This is the single most useful pattern: it turns a vague "the API returned 422" bug report into a runnable artifact.

3. Guzzle handler-stack middleware for non-Laravel code. For a raw GuzzleHttp\Client, push a middleware that converts each request, either into a PSR-3 debug log or into a Middleware::history() container you inspect later. This keeps the conversion out of every call site and makes it switchable per client instance (e.g. only the "third-party billing" client logs curl).

4. Base-class hook in a Laravel API wrapper. If you have several Services\*Client classes, put the conversion in a shared trait/base class and expose a curlFor($request) helper. Centralizing it means one place to add redaction and one place to swap the implementation if the package goes unmaintained.

5. Bug reports and documentation. Paste the generated command into issue templates, PR descriptions, or integration docs. It's genuinely better than documenting headers in a table because recipients can run it immediately. Keep a "reproduce with" snippet in your internal wiki for each third-party integration.

6. Local verification loop. Use php artisan tinker to build the request, print the curl string, and run it. This decouples "is the API broken?" from "is our Laravel/Guzzle config broken?" — timeouts, proxies, TLS settings, and content-type quirks surface fast.

7. Redaction wrapper. Build a thin CurlDumper service that clones the request, replaces sensitive headers, optionally truncates very large bodies for log readability, then delegates to Cuzzle. That gives you a single, testable place to enforce what leaves the process.

Gotchas and Tips

  • Body streams get consumed. PSR-7 bodies are streams; reading a body to build the curl string can leave the pointer at EOF, causing the real request to send an empty payload. Rewind before and after ($request->getBody()->rewind()), or clone the request before formatting. This is the most common way this package breaks working code.
  • Secrets leak into logs. Authorization, Cookie, X-Api-Key, and signed query strings will be printed verbatim. Redact before logging, and check your log retention/aggregation before enabling this in staging.
  • Multipart and file uploads don't round-trip. A multipart/form-data request with a file stream cannot be faithfully represented as a curl string; expect placeholders or inline content. Use -F manually for those cases.
  • Shell quoting differences. Generated commands are typically single-quoted bash style. Pasting into PowerShell/cmd will fail or mangle JSON payloads. On Windows, run through WSL/Git Bash or hand-edit quoting. The 3.1.0 Windows test fixes are test-suite fixes, not a change to generated shell quoting.
  • Redirects and retries are invisible. The string reflects one request object, not a redirect chain or Laravel's ->retry() attempts. With beforeSending, you'll get one line per attempt — make sure you log which attempt failed.
  • Large or binary bodies. Cuzzle 3.1.0 adds support for formatting large request bodies, so you no longer need to pre-truncate solely to get output. Still treat huge/binary payloads carefully: dumping multi-megabyte JSON bloats logs, and multipart/file streams are not faithfully represented. Apply a max-size policy in your redaction/truncation wrapper.
  • Maintenance risk. A 3.1.0 release exists (large-body formatting plus Windows test fixes), but still verify Composer resolves against your Guzzle 7.x and Laravel version (composer require octoper/cuzzle -W and read the solver output). Isolate the dependency behind your own small CurlDumper interface so a replacement — even a 30-line handwritten string builder — is a one-file change. For the common case (method, URL, headers, body), the fallback is trivial.
  • Debugging the generator itself. If the output looks wrong, run the produced command with -v and compare against Guzzle's own debug => true output. Differences usually come from Guzzle's default headers (User-Agent, Content-Length) or option-level behaviour (http_errors, timeout, verify) that curl doesn't share — remember the generated command reproduces the request, not the client configuration.
  • Extension point. The package separates conversion from formatting; if you need a different output shape (e.g. an array of arguments for a UI, or masked output), wrapping or replacing the formatter is cleaner than string-munging the result.
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.
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console