Weave Code
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

Services Bundle Laravel Package

brunopicci/services-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require brunopicci/services-bundle
    

    Add the bundle to config/app.php under providers:

    Brunopicci\ServicesBundle\ServicesBundle::class,
    
  2. Publish Configuration (if needed):

    php artisan vendor:publish --provider="Brunopicci\ServicesBundle\ServicesBundle" --tag="config"
    

    This generates a config file at config/services-bundle.php.

  3. First Use Case: Inject the ServicesBundle service into a controller or command:

    use Brunopicci\ServicesBundle\ServicesBundle;
    
    public function __construct(private ServicesBundle $servicesBundle) {}
    
    public function callApi()
    {
        $response = $this->servicesBundle->call('https://api.example.com/endpoint', 'GET');
        return $response; // Returns decoded JSON as array
    }
    

Implementation Patterns

Core Workflows

  1. Basic API Calls: Use the call() method for simple requests:

    $this->servicesBundle->call('https://api.example.com/users', 'GET');
    
    • Returns decoded JSON by default.
  2. Raw JSON Response: Pass false as the third argument to avoid decoding:

    $rawResponse = $this->servicesBundle->call('https://api.example.com/users', 'GET', false);
    
  3. POST/PUT/PATCH Requests with Data: Pass an array as the third argument for the request body:

    $this->servicesBundle->call(
        'https://api.example.com/users',
        'POST',
        ['name' => 'John Doe', 'email' => 'john@example.com']
    );
    
  4. Custom Headers: Use the withHeaders() method to attach headers:

    $this->servicesBundle->withHeaders(['Authorization' => 'Bearer token'])
        ->call('https://api.example.com/protected', 'GET');
    
  5. Configuration via Config File: Define default settings in config/services-bundle.php:

    'default_headers' => [
        'Accept' => 'application/json',
        'Content-Type' => 'application/json',
    ],
    'timeout' => 30,
    

Integration Tips

  • Dependency Injection: Bind the service to a custom interface for better testability:

    $this->app->bind(
        \App\Contracts\ApiClient::class,
        function ($app) {
            return $app->make(Brunopicci\ServicesBundle\ServicesBundle::class);
        }
    );
    
  • Error Handling: Wrap calls in a try-catch block to handle exceptions:

    try {
        $response = $this->servicesBundle->call('https://api.example.com/users', 'GET');
    } catch (\Exception $e) {
        Log::error('API call failed: ' . $e->getMessage());
        return response()->json(['error' => 'Service unavailable'], 503);
    }
    
  • Rate Limiting: Use Laravel's throttle middleware for API rate limiting:

    Route::middleware(['throttle:60,1'])->group(function () {
        Route::get('/api-data', [YourController::class, 'callApi']);
    });
    

Gotchas and Tips

Pitfalls

  1. No Built-in Retry Logic: The bundle does not implement automatic retries for failed requests. Use a library like spatie/retries or implement custom logic:

    use Spatie\Retry\Retry;
    
    Retry::times(3)->attempt(function () {
        $this->servicesBundle->call('https://api.example.com/users', 'GET');
    });
    
  2. Configuration Overrides: If you publish the config file, ensure you merge it correctly in config/app.php to avoid conflicts:

    'services-bundle' => [
        'timeout' => env('API_TIMEOUT', 30),
        // Other overrides...
    ],
    
  3. No Middleware Support: The bundle does not support Laravel middleware out of the box. For advanced use cases, extend the service:

    class CustomServicesBundle extends ServicesBundle
    {
        public function call($url, $method, $data = [], $decode = true)
        {
            $this->middleware->dispatch(new Request());
            return parent::call($url, $method, $data, $decode);
        }
    }
    
  4. Deprecated Methods: The bundle is under heavy development. Check the README or CHANGELOG for breaking changes between versions.

Debugging Tips

  1. Enable Guzzle Debugging: Add this to your config/services-bundle.php to log requests:

    'debug' => env('APP_DEBUG', false),
    
  2. Inspect Raw Responses: Use the false decode parameter to debug raw responses:

    $raw = $this->servicesBundle->call('https://api.example.com/users', 'GET', [], false);
    Log::debug('Raw response:', ['response' => $raw]);
    
  3. Validate API Responses: Use Laravel's Validator to validate responses:

    $response = $this->servicesBundle->call('https://api.example.com/users', 'GET');
    $validator = Validator::make($response, [
        'data.*.id' => 'required|integer',
        'data.*.name' => 'required|string',
    ]);
    

Extension Points

  1. Custom Response Handling: Extend the bundle to transform responses:

    class ExtendedServicesBundle extends ServicesBundle
    {
        public function call($url, $method, $data = [], $decode = true)
        {
            $response = parent::call($url, $method, $data, $decode);
            return $this->transformResponse($response);
        }
    
        protected function transformResponse($response)
        {
            // Custom logic (e.g., flatten arrays, add metadata)
            return $response;
        }
    }
    
  2. Add Authentication: Create a decorator for authentication:

    class AuthenticatedServicesBundle extends ServicesBundle
    {
        public function call($url, $method, $data = [], $decode = true)
        {
            $this->withHeaders(['Authorization' => $this->getAuthToken()]);
            return parent::call($url, $method, $data, $decode);
        }
    
        private function getAuthToken()
        {
            return 'Bearer ' . Auth::user()->apiToken;
        }
    }
    
  3. Support for Async Requests: Use Laravel Queues to offload API calls:

    dispatch(new CallApiJob('https://api.example.com/users', 'GET'));
    
    class CallApiJob implements ShouldQueue
    {
        use Dispatchable, InteractsWithQueue, Queueable;
    
        public function handle()
        {
            $response = app(ServicesBundle::class)->call($this->url, $this->method);
            // Process response...
        }
    }
    
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.
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle
atriumphp/atrium
sandermuller/package-boost-laravel
sandermuller/boost-skills
redaxo/core
yusufgenc/filament-api-forge
l3aro/rating-star-for-filament
leek/filament-subtenant-scope