PHPackages                             motomedialab/connector - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [HTTP &amp; Networking](/categories/http)
4. /
5. motomedialab/connector

ActiveLibrary[HTTP &amp; Networking](/categories/http)

motomedialab/connector
======================

A super lightweight request/connector pattern to make light work of API authentication and calls

1.0.0(3mo ago)236111MITPHPPHP ^8.2CI passing

Since Jan 15Pushed 3mo agoCompare

[ Source](https://github.com/motomedialab/connector)[ Packagist](https://packagist.org/packages/motomedialab/connector)[ Docs](https://github.com/motomedialab/connector)[ RSS](/packages/motomedialab-connector/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (1)Dependencies (5)Versions (2)Used By (1)

MotoMediaLab Connector
======================

[](#motomedialab-connector)

[![MIT License](https://camo.githubusercontent.com/784362b26e4b3546254f1893e778ba64616e362bd6ac791991d2c9e880a3a64e/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c6963656e73652d4d49542d677265656e2e737667)](https://choosealicense.com/licenses/mit/)[![Latest Version on Packagist](https://camo.githubusercontent.com/c158fb42731d207e7969def9800ab79b0a0187b704e5a210ae142384bfd112a1/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f6d6f746f6d656469616c61622f636f6e6e6563746f722e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/motomedialab/connector)[![Total Downloads](https://camo.githubusercontent.com/06a7ca57cc253aa973726346acd2847cb45377e619b8fbb78fe56b00750b6120/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f6d6f746f6d656469616c61622f636f6e6e6563746f722e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/motomedialab/connector)[![Tests](https://github.com/motomedialab/connector/actions/workflows/tests.yml/badge.svg)](https://github.com/motomedialab/connector/actions/workflows/tests.yml)

A super lightweight, opinionated connector pattern for Laravel to make light work of consuming third-party APIs.

Introduction
------------

[](#introduction)

Integrating with external APIs often involves repetitive boilerplate for handling authentication, endpoints, and requests. This package provides a structured and reusable pattern to streamline this process, keeping your code clean, consistent, and easy to maintain.

Installation
------------

[](#installation)

You can install the package via composer:

```
composer require motomedialab/connector
```

Core Concepts
-------------

[](#core-concepts)

The package is built around two core concepts: [Connectors](#connectors) and [Requests](#requests).

### Connectors

[](#connectors)

The `Connector` is responsible for defining the base URL and authentication method for an API. Your connector **must** extend the `Motomedialab\Connector\BaseConnector` abstract class.

```
// app/Connectors/ExampleConnector.php
use Illuminate\Http\Client\PendingRequest;
use Motomedialab\Connector\BaseConnector;

class ExampleConnector extends BaseConnector
{
    /**
     * Optionally authenticate all requests from this connector.
     * For example, an access or bearer token.
     */
    public function authenticateRequest(PendingRequest $request): PendingRequest
    {
        return $request->withToken('your-secret-token');
    }

    /**
     * Define the base URL for the API you are connecting with
     */
    public function apiUrl(): string
    {
        return 'https://api.example.com/v2/';
    }
}
```

### Requests

[](#requests)

The `Request` defines the specific details of an API call, such as the endpoint, method, headers, and payload. Your request classes **must** extend the `Motomedialab\Connector\BaseRequest` abstract class and **should** implement the `Motomedialab\Connector\Contracts\RequestInterface` contract.

The `BaseRequest` provides sensible defaults, so you only need to define what you need to override.

#### Simple GET Request

[](#simple-get-request)

Here's a minimal example for a simple GET request:

```
// app/Requests/ExampleGetRequest.php
use Illuminate\Http\Client\Response;
use Motomedialab\Connector\BaseRequest;
use Motomedialab\Connector\Contracts\RequestInterface;

/**
 * @implements RequestInterface
 */
readonly class ExampleGetRequest extends BaseRequest implements RequestInterface
{
    public function __construct(private string $id)
    {
       //
    }

    public function endpoint(): string
    {
        return "users/{$this->id}";
    }

    public function toResponse(Response $response): array
    {
        return $response->json();
    }
}
```

#### Advanced POST Request

[](#advanced-post-request)

This example demonstrates all available methods for customising a request.

```
// app/Requests/ExamplePostRequest.php
use Illuminate\Http\Client\Response;
use Motomedialab\Connector\BaseRequest;
use Motomedialab\Connector\Enums\RequestMethod;
use Motomedialab\Connector\Contracts\RequestInterface;

/**
 * @implements RequestInterface
 */
readonly class ExamplePostRequest extends BaseRequest implements RequestInterface
{
    public function __construct(public array $inputData = [])
    {
      //
    }

    // Define the HTTP method. Defaults to GET.
    public function method(): RequestMethod
    {
        return RequestMethod::POST;
    }

    // Specify the request timeout in seconds. Defaults to 5.
    public function timeout(): int
    {
        return 10;
    }

    // Add query parameters to the URL.
    public function queryParams(): array
    {
        return ['include' => 'posts'];
    }

    // Add or override headers. Defaults include JSON content type.
    public function headers(): array
    {
        return [
            ...parent::headers(),
            'X-Custom-Header' => 'CustomValue',
        ];
    }

    // REQUIRED: Define the endpoint, appended to the connector's apiUrl.
    public function endpoint(): string
    {
        return 'users';
    }

    // Define the request payload.
    public function body(): array
    {
        return $this->inputData;
    }

    // Determine if the request requires authentication. Defaults to true.
    public function authenticated(): bool
    {
        return true;
    }

    // Transform the successful response.
    public function toResponse(Response $response): array
    {
        if ($response->failed()) {
            // You can handle error responses here.
            // For example, return a default structure or throw an exception.
            return ['error' => true, 'status' => $response->status()];
        }

        return $response->json();
    }
}
```

Usage
-----

[](#usage)

### Sending a Request

[](#sending-a-request)

To send a request, simply instantiate your connector and request, then call the `send()` method.

```
$connector = new ExampleConnector();
$request = new ExamplePostRequest(['name' => 'Chris']);

// The response will be whatever you return from toResponse()
$response = $connector->send($request);
```

### Asynchronous Requests

[](#asynchronous-requests)

You can also send requests concurrently using the `sendAsync()` method. This is great for performance when you need to make multiple independent API calls.

```
use GuzzleHttp\Promise\Utils;

$connector = new ExampleConnector();

// Create an array of requests
$requests = [
    new ExampleGetRequest('user-1'),
    new ExampleGetRequest('user-2'),
    new ExampleGetRequest('user-3'),
];

// Map requests to promises
$promises = array_map(
    fn($request) => $connector->sendAsync($request),
    $requests
);

// Wait for all promises to resolve
$responses = Utils::unwrap($promises);
```

Testing
-------

[](#testing)

This package is designed to work seamlessly with Laravel's `Http::fake()`. You can write your tests as you normally would.

```
use Illuminate\Support\Facades\Http;
use App\Connectors\ExampleConnector;
use App\Requests\ExampleGetRequest;

it('sends a get request', function () {
    Http::fake([
        'api.example.com/*' => Http::response(['name' => 'John']),
    ]);

    $connector = new ExampleConnector();
    $response = $connector->send(new ExampleGetRequest('user-1'));

    expect($response['name'])->toBe('John');
});
```

Contributing
------------

[](#contributing)

Please see [CONTRIBUTING](CONTRIBUTING.md) for details.

License
-------

[](#license)

The MIT License (MIT). Please see [License File](LICENSE.md) for more information.

###  Health Score

41

—

FairBetter than 89% of packages

Maintenance78

Regular maintenance activity

Popularity20

Limited adoption so far

Community11

Small or concentrated contributor base

Maturity46

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Unknown

Total

1

Last Release

117d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/805ae1048fb81d8f02871f57cc0a34699089da17f7021210e554ffdba4df918a?d=identicon)[chrispage1](/maintainers/chrispage1)

---

Top Contributors

[![chrispage1](https://avatars.githubusercontent.com/u/2487374?v=4)](https://github.com/chrispage1 "chrispage1 (3 commits)")

---

Tags

Guzzleconnectormotomedialablaravel-httprequest-pattern

###  Code Quality

TestsPest

Static AnalysisPHPStan

Code StyleLaravel Pint

### Embed Badge

![Health badge](/badges/motomedialab-connector/health.svg)

```
[![Health](https://phpackages.com/badges/motomedialab-connector/health.svg)](https://phpackages.com/packages/motomedialab-connector)
```

###  Alternatives

[ezimuel/guzzlestreams

Fork of guzzle/streams (abandoned) to be used with elasticsearch-php

176108.6M3](/packages/ezimuel-guzzlestreams)[kevinrob/guzzle-cache-middleware

A HTTP/1.1 Cache for Guzzle 6. It's a simple Middleware to be added in the HandlerStack. (RFC 7234)

43117.4M104](/packages/kevinrob-guzzle-cache-middleware)[caseyamcl/guzzle_retry_middleware

Guzzle v6+ retry middleware that handles 429/503 status codes and connection timeouts

21610.7M64](/packages/caseyamcl-guzzle-retry-middleware)[php-http/guzzle7-adapter

Guzzle 7 HTTP Adapter

9057.1M555](/packages/php-http-guzzle7-adapter)[namu/wirechat

A Laravel Livewire messaging app for teams with private chats and group conversations.

54324.5k](/packages/namu-wirechat)[remic/guzzlecache

Laravel 5 package for caching Guzzle's GET requests.

189.3k](/packages/remic-guzzlecache)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
