PHPackages                             cubesystems/api-client - 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. cubesystems/api-client

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

cubesystems/api-client
======================

API Client provides a modular way to consume API's for Laravel.

v3.0.0(2y ago)04.9k↓33.3%3MITPHPPHP 8.0.\*

Since Nov 4Pushed 2y ago4 watchersCompare

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

READMEChangelog (1)Dependencies (16)Versions (5)Used By (0)

API Client
==========

[](#api-client)

This package defines contracts and provides abstract partial implementations of those contracts. It is meant to be used as a base building block for your own highly modular and customisable implementation of API consumption. Feel free to use as little or as much of it as you need.

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

[](#installation)

You can install the package via composer:

```
composer require cubesystems/api-client
```

Configuration
-------------

[](#configuration)

To use Laravel Debugbar integration, enable it within `debugbar.php` config file:

```
return [
    ...
    'collectors' => [
        ...
        'api' => true
    ]
];
```

Creating custom API client implementation
-----------------------------------------

[](#creating-custom-api-client-implementation)

First of all, let's define some vocabulary.

### SOAP

[](#soap)

[![Method vs service vs endpoint](images/soap.png)](images/soap.png) *Methods, services and endpoints*

### REST

[](#rest)

[![Method vs service vs endpoint](images/rest.png)](images/rest.png) *Methods, services and endpoints*

After this, we can look at the relations between all interfaces:

[![Interfaces](images/er.png)](images/er.png) *Relationship between main interfaces*

### Define an endpoint

[](#define-an-endpoint)

For this, we need to implement `CubeSystems\ApiClient\Client\Contracts\Endpoint` contract which can be done by extending `CubeSystems\ApiClient\Client\AbstractRestEndpoint` or `CubeSystems\ApiClient\Client\AbstractSoapEndpoint` class:

```
use CubeSystems\ApiClient\Client\AbstractSoapEndpoint;

class MyEndpoint extends AbstractSoapEndpoint {}
```

### Define a service accessible within an endpoint

[](#define-a-service-accessible-within-an-endpoint)

For this, we need to implement `CubeSystems\ApiClient\Client\Contracts\Service` contract which can be done by extending `CubeSystems\ApiClient\Client\AbstractRestService` or `CubeSystems\ApiClient\Client\AbstractSoapService` class:

```
use CubeSystems\ApiClient\Client\AbstractSoapService;

class MyService extends AbstractSoapService
{
    protected const SERVICE_PATH = 'path/to/service';
}
```

### Create a request payload class

[](#create-a-request-payload-class)

This can be done by implementing `CubeSystems\ApiClient\Client\Contracts\Payload` contract directly or by extending `CubeSystems\ApiClient\Client\Payloads\AbstractPayload` class:

```
use CubeSystems\ApiClient\Client\Payloads\AbstractPayload;

class MyPayload extends AbstractPayload
{
    private string $parameter;

    public function setId(string $id): MyPayload
    {
        $this->id = $id;

        return $this;
    }

    public function toArray(): array
    {
        return [
            'id' => $this->id
        ];
    }

    public function getCacheKey(): string
    {
        return self::class . $this->id;
    }
}
```

### Create a response class

[](#create-a-response-class)

This can be done by implementing `CubeSystems\ApiClient\Client\Contracts\Response` contract directly or by extending `CubeSystems\ApiClient\Client\Responses\AbstractResponse` class:

```
use CubeSystems\ApiClient\Client\Responses\AbstractResponse;

class MyResponse extends AbstractResponse
{
    private MyDto $myDto;

    public function getMyDto(): MyDto
    {
        return $this->myDto;
    }

    public function setMyDto(MyDto $myDto): MyResponse
    {
        $this->myDto = $myDto;

        return $this;
    }
}
```

### Create a method for a service

[](#create-a-method-for-a-service)

`CubeSystems\ApiClient\Client\Contracts\Method` is implemented by `CubeSystems\ApiClient\Client\Methods\AbstractRestMethod` and `CubeSystems\ApiClient\Client\Methods\AbstractSoapMethod` classes.

```
use CubeSystems\ApiClient\Client\Methods\AbstractSoapMethod;
use CubeSystems\ApiClient\Client\Plugs\PlugManager;
use CubeSystems\ApiClient\Client\Strategies\NeverCacheStrategy;
use Illuminate\Support\Arr;

class MyMethod extends AbstractSoapMethod
{
    protected const METHOD_NAME = 'MyMethod';

    public function __construct(
        MyService $service,
        NeverCacheStrategy $cacheStrategy,
        PlugManager $plugManager,
    ) {
        parent::__construct($service, $cacheStrategy, $plugManager);
    }

    protected function toResponse(array $rawResponse, int $httpCode): MyResponse
    {
        $response = new MyResponse();
        ...
        $myDto = new MyDto();
        $myDto->setName(Arr::get($rawResponse, 'name'));
        $myDto->setAge((int) Arr::get($rawResponse, 'age'));
        $response->setDto($myDto);

        return $response;
    }
}
```

Calling an API
--------------

[](#calling-an-api)

After all that, you can make calls like this:

```
use Foo\Endpoints\MyEndpoint;
use Foo\Services\MyService;
use Foo\Methods\MyMethod;
use Foo\Payloads\MyPayload;

class MyRepository
{
    public function getMyDtoById(string $id): MyDto
    {
        $myEndpoint = new MyEndpoint(config('api-client.endpoints.myEndpoint.url'));
        $myService = new MyService($myEndpoint, collect(), collect(), new ApiClient());
        $myMethod = new MyMethod($myService, new NeverCacheStrategy());
        $myPayload = new MyPayload();
        $myPayload->setId($id);

        return $myMethod->call($myPayload)->getMyDto();
    }
}
```

Or take advantage of dependency injection done by Laravel.

Extend `CubeSystems\ApiClient\ApiClientServiceProvider` class and register your bindings:

```
public function register(): void
{
    parent::register();

    $this->app->singleton(MyEndpoint::class, function (Application $app) {
        $url = config('api-client.endpoints.myEndpoint.url');

        return new MyEndpoint($url);
    });
}
```

Now the same thing can be done more concisely:

```
use Foo\Methods\MyMethod;
use Foo\Payloads\MyPayload;

class MyRepository
{
    public function getMyDtoById(string $id): MyDto
    {
        $myMethod = app(MyMethod::class);
        $myPayload = new MyPayload();
        $myPayload->setId($id);

        return $myMethod->call($myPayload)->getMyDto();
    }
}
```

Take a look at tests for more detailed examples.

Caching
-------

[](#caching)

`AbstractMethod` class includes a caching mechanism. Just pass desired cache strategy to the constructor. There are 3 strategies available:

- `CubeSystems\ApiClient\Client\Cache\NeverCacheStrategy` - never cache the response
- `CubeSystems\ApiClient\Client\Cache\RequestCacheStrategy` - cache the response for the duration of the request
- `CubeSystems\ApiClient\Client\Cache\TimeIntervalCacheStrategy` - cache the response for a given time interval

You can also create your own strategy by implementing `CubeSystems\ApiClient\Client\Contracts\CacheStrategy` contract.

`CubeSystems\ApiClient\Client\Contracts\Payload::getCacheKey()` method is used to decide if there are valid cache entries for a given payload. If there are, the response is retrieved from cache. Otherwise, the remote API is called.

### Hierarchical caching

[](#hierarchical-caching)

If payload returns `true` from `isUsingCacheHierarchy` method, then corresponding call will be made part of the cache hierarchy. This allows to invalidate all cache entries for given hierarchy at once by calling `AbstractMethod`'s `removeHierarchyFromCache` method.

For this to work, `CubeSystems\ApiClient\Client\Contracts\Payload::getCacheHierarchyKey` method must be implemented according to your needs.

Moreover, `AbstractPayload` now accepts optional `CachePrefix` parameter which can be used to differentiate between cache hierarchies for the same *type* of method and payload. Typical use case would be to distinguish between different users' cache hierarchies.

There is more
-------------

[](#there-is-more)

### Events

[](#events)

`CubeSystems\ApiClient\Client\Methods\AbstractMethod` class fires the following events:

- `CubeSystems\ApiClient\Events\ApiCalled` - after a remote API is called
- `CubeSystems\ApiClient\Events\ResponseRetrievedFromCache` - after response is retrieved from cache without calling a remote API

You can listen to those and do some additional stuff like logging.

### Laravel Debugbar integration

[](#laravel-debugbar-integration)

If `debugbar.collectors.api` configuration option is set to `true` as described above, all API calls (and cache retrievals) will be visible within Laravel Debugbar:

[![Debugbar integration](images/debugbar.png)](images/debugbar.png) *Debugbar integration*

Testing
-------

[](#testing)

This package uses [Pest testing framework](https://pestphp.com/). You can run tests with

```
composer test
```

Changelog
---------

[](#changelog)

Please see [CHANGELOG](CHANGELOG.md) for more information on what has changed recently.

###  Health Score

31

—

LowBetter than 68% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity24

Limited adoption so far

Community24

Small or concentrated contributor base

Maturity51

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 56.9% 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

Every ~31 days

Total

4

Last Release

833d ago

Major Versions

v1.4.0 → v2.0.02023-12-04

v2.0.0 → v3.0.02024-02-06

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/686243?v=4)[Miks Miķelsons](/maintainers/miks)[@miks](https://github.com/miks)

---

Top Contributors

[![freekmurze](https://avatars.githubusercontent.com/u/483853?v=4)](https://github.com/freekmurze "freekmurze (331 commits)")[![RihardsZ](https://avatars.githubusercontent.com/u/3199845?v=4)](https://github.com/RihardsZ "RihardsZ (49 commits)")[![mvdnbrk](https://avatars.githubusercontent.com/u/802681?v=4)](https://github.com/mvdnbrk "mvdnbrk (46 commits)")[![pforret](https://avatars.githubusercontent.com/u/474312?v=4)](https://github.com/pforret "pforret (16 commits)")[![sebastiandedeyne](https://avatars.githubusercontent.com/u/1561079?v=4)](https://github.com/sebastiandedeyne "sebastiandedeyne (14 commits)")[![exabyssus](https://avatars.githubusercontent.com/u/6299387?v=4)](https://github.com/exabyssus "exabyssus (13 commits)")[![Nielsvanpach](https://avatars.githubusercontent.com/u/10651054?v=4)](https://github.com/Nielsvanpach "Nielsvanpach (13 commits)")[![dependabot[bot]](https://avatars.githubusercontent.com/in/29110?v=4)](https://github.com/dependabot[bot] "dependabot[bot] (11 commits)")[![anastasijagolubeva](https://avatars.githubusercontent.com/u/134049119?v=4)](https://github.com/anastasijagolubeva "anastasijagolubeva (8 commits)")[![github-actions[bot]](https://avatars.githubusercontent.com/in/15368?v=4)](https://github.com/github-actions[bot] "github-actions[bot] (8 commits)")[![AdrianMrn](https://avatars.githubusercontent.com/u/12762044?v=4)](https://github.com/AdrianMrn "AdrianMrn (8 commits)")[![AlexVanderbist](https://avatars.githubusercontent.com/u/6287961?v=4)](https://github.com/AlexVanderbist "AlexVanderbist (7 commits)")[![riasvdv](https://avatars.githubusercontent.com/u/3626559?v=4)](https://github.com/riasvdv "riasvdv (7 commits)")[![irfanm96](https://avatars.githubusercontent.com/u/42065936?v=4)](https://github.com/irfanm96 "irfanm96 (5 commits)")[![patinthehat](https://avatars.githubusercontent.com/u/5508707?v=4)](https://github.com/patinthehat "patinthehat (5 commits)")[![IGedeon](https://avatars.githubusercontent.com/u/694313?v=4)](https://github.com/IGedeon "IGedeon (4 commits)")[![crynobone](https://avatars.githubusercontent.com/u/172966?v=4)](https://github.com/crynobone "crynobone (4 commits)")[![abenerd](https://avatars.githubusercontent.com/u/7523903?v=4)](https://github.com/abenerd "abenerd (3 commits)")[![jessarcher](https://avatars.githubusercontent.com/u/4977161?v=4)](https://github.com/jessarcher "jessarcher (3 commits)")[![koossaayy](https://avatars.githubusercontent.com/u/6431084?v=4)](https://github.com/koossaayy "koossaayy (3 commits)")

---

Tags

apilaravelrestcachingsoap

###  Code Quality

TestsPest

Code StyleLaravel Pint

### Embed Badge

![Health badge](/badges/cubesystems-api-client/health.svg)

```
[![Health](https://phpackages.com/badges/cubesystems-api-client/health.svg)](https://phpackages.com/packages/cubesystems-api-client)
```

###  Alternatives

[omniphx/forrest

A Laravel library for Salesforce

2724.4M8](/packages/omniphx-forrest)[binaryk/laravel-restify

Laravel REST API helpers

651399.1k](/packages/binaryk-laravel-restify)[pusher/pusher-http-laravel

\[DEPRECATED\] A Pusher bridge for Laravel

400509.0k3](/packages/pusher-pusher-http-laravel)[sunchayn/nimbus

A Laravel package providing an in-browser API client with automatic schema generation, live validation, and built-in authentication with a touch of Laravel-tailored magic for effortless API testing.

29428.0k](/packages/sunchayn-nimbus)[api-platform/laravel

API Platform support for Laravel

59126.4k6](/packages/api-platform-laravel)[guanguans/laravel-api-response

Normalize and standardize Laravel API response data structure. - 规范化和标准化 Laravel API 响应数据结构。

485.6k](/packages/guanguans-laravel-api-response)

PHPackages © 2026

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