PHPackages                             swisnl/json-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. [API Development](/categories/api)
4. /
5. swisnl/json-api-client

ActiveLibrary[API Development](/categories/api)

swisnl/json-api-client
======================

A PHP package for mapping remote JSON:API resources to Eloquent like models and collections.

2.6.2(2mo ago)211473.2k—9.5%27[3 issues](https://github.com/swisnl/json-api-client/issues)8MITPHPPHP ^8.0CI passing

Since Sep 5Pushed 2mo ago11 watchersCompare

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

READMEChangelog (10)Dependencies (26)Versions (69)Used By (8)

{ json:api } Client
===================

[](#-jsonapi--client)

[![PHP from Packagist](https://camo.githubusercontent.com/4511e46891b97448b05bbd389a47290cbf4e64cd438a0ea701eb3c1128dee8d6/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f7068702d762f737769736e6c2f6a736f6e2d6170692d636c69656e742e737667)](https://packagist.org/packages/swisnl/json-api-client)[![Latest Version on Packagist](https://camo.githubusercontent.com/3e40fe6cdc95550175230eaeac6bcaa3c9379c463a03a2c1429fb54a2aaf17fd/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f737769736e6c2f6a736f6e2d6170692d636c69656e742e737667)](https://packagist.org/packages/swisnl/json-api-client)[![Software License](https://camo.githubusercontent.com/16d3a8773cc0ffb56a5263c539f729284e44947c8655c1a99c554ea93ba58482/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f6c2f737769736e6c2f6a736f6e2d6170692d636c69656e742e737667)](LICENSE.md)[![Buy us a tree](https://camo.githubusercontent.com/195a3f79c3c2f91a69498ad26c1d8a7eeaf5771da0007200f409f5d438a515c4/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f54726565776172652d2546302539462538432542332d6c69676874677265656e2e737667)](https://plant.treeware.earth/swisnl/json-api-client)[![Build Status](https://camo.githubusercontent.com/c4715afdee9cc0bf398a4c6f0a0ca5e905a146d4c600e8eb3ef7c2ac3dcb16c2/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f636865636b732d7374617475732f737769736e6c2f6a736f6e2d6170692d636c69656e742f6d61737465723f6c6162656c3d7465737473)](https://github.com/swisnl/json-api-client/actions/workflows/tests.yml)[![Scrutinizer Coverage](https://camo.githubusercontent.com/19e10e3e7b562b14d1706fb66b08556898ed4191cb12a14314f702c8aa57df91/68747470733a2f2f696d672e736869656c64732e696f2f7363727574696e697a65722f636f7665726167652f672f737769736e6c2f6a736f6e2d6170692d636c69656e742e737667)](https://scrutinizer-ci.com/g/swisnl/json-api-client/?branch=master)[![Scrutinizer Code Quality](https://camo.githubusercontent.com/af03740bc87ee6c07383f9dcb9e19076b7898616cbda1980e22ebf16e2f67d6a/68747470733a2f2f696d672e736869656c64732e696f2f7363727574696e697a65722f672f737769736e6c2f6a736f6e2d6170692d636c69656e742e737667)](https://scrutinizer-ci.com/g/swisnl/json-api-client/?branch=master)[![Made by SWIS](https://camo.githubusercontent.com/8c541545402619860a7346c32a176d63a2b75eb8ebb85590d06a26b62417d260/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f2546302539462539412538302d6d6164652532306279253230535749532d2532333037333741392e737667)](https://www.swis.nl)

A PHP package for mapping remote [JSON:API](http://jsonapi.org/) resources to Eloquent like models and collections.

💡 Before we start, please note that this library can only be used for [JSON:API](http://jsonapi.org/) resources and requires some basic knowledge of the specification. If you are not familiar with {json:api}, please read [the excellent blog](https://laravel-news.com/json-api-introduction) by [Björn Brala](https://github.com/bbrala) for a quick introduction.

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

[](#installation)

ℹ️ Using Laravel? Take a look at [swisnl/json-api-client-laravel](https://github.com/swisnl/json-api-client-laravel) for easy Laravel integration.

```
composer require swisnl/json-api-client
```

N.B. Make sure you have installed a PSR-18 HTTP Client and PSR-17 HTTP Factories before you install this package or install one at the same time e.g. `composer require swisnl/json-api-client guzzlehttp/guzzle:^7.3`.

### HTTP Client

[](#http-client)

We are decoupled from any HTTP messaging client with the help of [PSR-18 HTTP Client](https://www.php-fig.org/psr/psr-18/) and [PSR-17 HTTP Factories](https://www.php-fig.org/psr/psr-17/). This requires an extra package providing [psr/http-client-implementation](https://packagist.org/providers/psr/http-client-implementation) and [psr/http-factory-implementation](https://packagist.org/providers/psr/http-factory-implementation). To use Guzzle 7, for example, simply require `guzzlehttp/guzzle`:

```
composer require guzzlehttp/guzzle:^7.3
```

See [HTTP Clients](#http-clients) if you want to use your own HTTP client or use specific configuration options.

Getting started
---------------

[](#getting-started)

You can simply create an instance of [DocumentClient](#documentclient) and use it in your class. Alternatively, you can create a [repository](#repository).

```
use Swis\JsonApi\Client\DocumentClient;

$client = DocumentClient::create();
$document = $client->get('https://cms.contentacms.io/api/recipes');

/** @var \Swis\JsonApi\Client\Collection&\Swis\JsonApi\Client\Item[] $collection */
$collection = $document->getData();

foreach ($collection as $item) {
  // Do stuff with the items
}
```

Items
-----

[](#items)

By default, all items are an instance of `\Swis\JsonApi\Client\Item`. The `Item` provides a Laravel Eloquent-like base class.

You can define your own models by extending `\Swis\JsonApi\Client\Item` or by implementing the `\Swis\JsonApi\Client\Interfaces\ItemInterface` yourself. This can be useful if you want to define, for example, hidden attributes, casts or get/set mutators. If you use custom models, you must register them with the [TypeMapper](#typemapper).

### Relations

[](#relations)

This package implements [Laravel Eloquent-like relations](https://laravel.com/docs/eloquent-relationships). These relations provide a fluent interface to retrieve the related items. There are currently four relations available:

- `HasOneRelation`
- `HasManyRelation`
- `MorphToRelation`
- `MorphToManyRelation`

Please see the following example about defining the relationships:

```
use Swis\JsonApi\Client\Item;

class AuthorItem extends Item
{
    protected $type = 'author';

    public function blogs()
    {
        return $this->hasMany(BlogItem::class);
    }
}

class BlogItem extends Item
{
    protected $type = 'blog';

    public function author()
    {
        return $this->hasOne(AuthorItem::class);
    }
}
```

#### Naming support

[](#naming-support)

Relations should be defined using camelCase methods. Related items can then be accessed via magic attributes in camelCase or snake\_case or by using the explicit name you used when defining the relation.

Collections
-----------

[](#collections)

This package uses [Laravel Collections](https://laravel.com/docs/collections) as a wrapper for item arrays.

Links
-----

[](#links)

All objects that can have links (i.e. document, error, item and relationship) use `Concerns/HasLinks` and thus have a `getLinks` method that returns an instance of `Links`. This is a simple array-like object with key-value pairs which are in turn an instance of `Link` or `null`.

### Example

[](#example)

Given the following JSON:

```
{
	"links": {
		"self": "http://example.com/articles"
	},
	"data": [{
		"type": "articles",
		"id": "1",
		"attributes": {
			"title": "JSON:API paints my bikeshed!"
		},
		"relationships": {
			"author": {
				"data": {
					"type": "people",
					"id": "9"
				},
				"links": {
					"self": "http://example.com/articles/1/author"
				}
			}
		},
		"links": {
			"self": "http://example.com/articles/1"
		}
	}]
}
```

You can get the links this way:

```
/** @var $document \Swis\JsonApi\Client\Document */

// Document links
$links = $document->getLinks();
echo $links->self->getHref(); // http://example.com/articles

// Item links
$links = $document->getData()->getLinks();
echo $links->self->getHref(); // http://example.com/articles/1

// Relationship links
$links = $document->getData()->author()->getLinks();
echo $links->self->getHref(); // http://example.com/articles/1/author
```

Meta
----

[](#meta)

All objects that can have meta information (i.e. document, error, item, jsonapi, link and relationship) use `Concerns/HasMeta` and thus have a `getMeta` method that returns an instance of `Meta`. This is a simple array-like object with key-value pairs.

### Example

[](#example-1)

Given the following JSON:

```
{
	"links": {
		"self": {
			"href": "http://example.com/articles/1",
			"meta": {
				"foo": "bar"
			}
		}
	},
	"data": {
		"type": "articles",
		"id": "1",
		"attributes": {
			"title": "JSON:API paints my bikeshed!"
		},
		"relationships": {
			"author": {
				"data": {
					"type": "people",
					"id": "9"
				},
				"meta": {
					"written_at": "2019-07-16T13:47:26"
				}
			}
		},
		"meta": {
			"copyright": "Copyright 2015 Example Corp."
		}
	},
	"meta": {
		"request_id": "a77ab2b4-7132-4782-8b5e-d94ebaff6e13"
	}
}
```

You can get the meta this way:

```
/** @var $document \Swis\JsonApi\Client\Document */

// Document meta
$meta = $document->getMeta();
echo $meta->request_id; // a77ab2b4-7132-4782-8b5e-d94ebaff6e13

// Link meta
$meta = $document->getLinks()->self->getMeta();
echo $meta->foo; // bar

// Item meta
$meta = $document->getData()->getMeta();
echo $meta->copyright; // Copyright 2015 Example Corp.

// Relationship meta
$meta = $document->getData()->author()->getMeta();
echo $meta->written_at; // 2019-07-16T13:47:26
```

TypeMapper
----------

[](#typemapper)

All custom models must be registered with the `TypeMapper`. This `TypeMapper` maps, as the name suggests, JSON:API types to custom [items](#items).

Repository
----------

[](#repository)

For convenience, this package includes a basic repository with several methods to work with [resources](https://jsonapi.org/format/#document-resource-objects). You can create a repository for each of the endpoints you use based on `\Swis\JsonApi\Client\Repository`. This repository then uses standard CRUD endpoints for all its actions.

```
class BlogRepository extends \Swis\JsonApi\Client\Repository
{
    protected $endpoint = 'blogs';
}
```

The above repository will have a method for all CRUD-actions. If you work with a read-only API and don't want to have all actions, you can build your own repository by extending `\Swis\JsonApi\Client\BaseRepository` and including just the actions/traits you need.

```
use Swis\JsonApi\Client\Actions\FetchMany;
use Swis\JsonApi\Client\Actions\FetchOne;

class BlogRepository extends \Swis\JsonApi\Client\BaseRepository
{
    use FetchMany;
    use FetchOne;

    protected $endpoint = 'blogs';
}
```

If this repository (pattern) doesn't fit your needs, you can create your own implementation using the [clients](#clients) provided by this package.

### Request parameters

[](#request-parameters)

All methods provided by the repository take extra parameters that will be appended to the url. This can be used, among other things, to add [include](https://jsonapi.org/format/#fetching-includes) and/or [pagination](https://jsonapi.org/format/#fetching-pagination) parameters:

```
$repository = new BlogRepository();
$repository->all(['include' => 'author', 'page' => ['limit' => 15, 'offset' => 0]]);
```

ItemHydrator
------------

[](#itemhydrator)

The `ItemHydrator` can be used to fill/hydrate an item and its relations using an associative array with attributes. This is useful if you would like to hydrate an item with POST data from your request:

```
$typeMapper = new TypeMapper();
$itemHydrator = new ItemHydrator($typeMapper);
$blogRepository = new BlogRepository(DocumentClient::create($typeMapper), new DocumentFactory());

$item = $itemHydrator->hydrate(
    $typeMapper->getMapping('blog'),
    request()->all(['title', 'author', 'date', 'content', 'tags']),
    request()->id
);
$blogRepository->save($item);
```

### Relations

[](#relations-1)

The `ItemHydrator` also hydrates (nested) relations. A relation must explicitly be listed on the item in the `$availableRelations` array in order to be hydrated. If we take the above example, we can use the following attributes array to hydrate a new blog item:

```
$attributes = [
    'title'   => 'Introduction to JSON:API',
    'author'  => [
        'id'       => 'f1a775ef-9407-40ba-93ff-7bd737888dc6',
        'name'     => 'Björn Brala',
        'homepage' => 'https://github.com/bbrala',
    ],
    'co-author' => null,
    'date'    => '2018-12-02 15:26:32',
    'content' => 'JSON:API was originally drafted in May 2013 by Yehuda Katz...',
    'media' => [],
    'tags'    => [
        1,
        15,
        56,
    ],
];
$itemDocument = $itemHydrator->hydrate($typeMapper->getMapping('blog'), $attributes);

echo json_encode($itemDocument, JSON_PRETTY_PRINT);

{
    "data": {
        "type": "blog",
        "attributes": {
            "title": "Introduction to JSON:API",
            "date": "2018-12-02 15:26:32",
            "content": "JSON:API was originally drafted in May 2013 by Yehuda Katz..."
        },
        "relationships": {
            "author": {
                "data": {
                    "type": "author",
                    "id": "f1a775ef-9407-40ba-93ff-7bd737888dc6"
                }
            },
            "co-author": {
                "data": null
            },
            "media": {
                "data": []
            },
            "tags": {
                "data": [{
                    "type": "tag",
                    "id": "1"
                }, {
                    "type": "tag",
                    "id": "15"
                }, {
                    "type": "tag",
                    "id": "56"
                }]
            }
        }
    },
    "included": [{
        "type": "author",
        "id": "f1a775ef-9407-40ba-93ff-7bd737888dc6",
        "attributes": {
            "name": "Björn Brala",
            "homepage": "https://github.com/bbrala"
        }
    }]
}
```

As you can see in this example, relations can be hydrated by id, or by an associative array with an id and more attributes. If the item is hydrated using an associative array, it will be included in the resulting json unless `setOmitIncluded(true)` is called on the relation. You can unset a relation by passing `null` for singular relations or an empty array for plural relations.

N.B. Morph relations require a 'type' attribute to be present in the data in order to know which type of item should be created.

Handling errors
---------------

[](#handling-errors)

A request can fail due to several reasons and how this is handled depends on what happened. If the `DocumentClient` encounters an error there are basically three options.

#### Non 2xx request without body

[](#non-2xx-request-without-body)

If a response does not have a successful status code (2xx) and does not have a body, the `DocumentClient` (and therefore also the `Repository`) will return an instance of `InvalidResponseDocument`.

#### Non 2xx request with invalid JSON:API body

[](#non-2xx-request-with-invalid-jsonapi-body)

If a response does not have a successful status code (2xx) and does have a body, it is parsed as if it's a JSON:API document. If the response can not be parsed as such document, a `ValidationException` will be thrown.

#### Non 2xx request with valid JSON:API body

[](#non-2xx-request-with-valid-jsonapi-body)

If a response does not have a successful status code (2xx) and does have a body, it is parsed as if it's a JSON:API document. In this case the `DocumentClient` (and therefore also the `Repository`) will return an instance of `Document`. This document contains the errors from the response, assuming the server responded with errors.

### Checking for errors

[](#checking-for-errors)

Based on the above rules you can check for errors like this:

```
$document = $repository->all();

if ($document instanceof InvalidResponseDocument || $document->hasErrors()) {
    // do something with errors
}
```

Clients
-------

[](#clients)

This package offers two clients; `DocumentClient` and `Client`.

### DocumentClient

[](#documentclient)

This is the client that you would generally use e.g. the repository uses this client internally. Per the [JSON:API spec](http://jsonapi.org/format/#document-structure), all requests and responses are documents. Therefore, this client always expects a `\Swis\JsonApi\Client\Interfaces\DocumentInterface` as input when posting data and always returns this same interface. This can be a plain `Document` when there is no data, an `ItemDocument` for an item, a `CollectionDocument` for a collection or an `InvalidResponseDocument` when the server responds with a non 2xx response.

The `DocumentClient` follows the following steps internally:

1. Send the request using your HTTP client;
2. Use `ResponseParser` to parse and validate the response;
3. Create the correct document instance;
4. Hydrate every item by using the item model registered with the `TypeMapper` or a `\Swis\JsonApi\Client\Item` as fallback;
5. Hydrate all relationships;
6. Add meta data to the document such as [errors](http://jsonapi.org/format/#errors), [links](http://jsonapi.org/format/#document-links) and [meta](http://jsonapi.org/format/#document-meta).

### Client

[](#client)

This client is a more low level client and can be used, for example, for posting binary data such as images. It can take everything your request factory takes as input data and returns the 'raw' `\Psr\Http\Message\ResponseInterface`. It does not parse or validate the response or hydrate items!

DocumentFactory
---------------

[](#documentfactory)

The `DocumentClient` requires `ItemDocumentInterface` instances when creating or updating resources. Such documents can easily be created using the `DocumentFactory` by giving it a `DataInterface` instance. This can be an `ItemInterface`, usually created by the [ItemHydrator](#itemhydrator), or a `Collection`.

HTTP Clients
------------

[](#http-clients)

By default the `Client` uses [php-http/discovery](https://github.com/php-http/discovery) to find an available HTTP client, request factory and stream factory so you don't have to setup those yourself. You can also specify your own HTTP client, request factory or stream factory. This is a perfect way to add extra options to your HTTP client or register a mock HTTP client for your tests:

```
if (app()->environment('testing')) {
    $httpClient = new \Swis\Http\Fixture\Client(
        new \Swis\Http\Fixture\ResponseBuilder('/path/to/fixtures')
    );
} else {
    $httpClient = new \GuzzleHttp\Client(
        [
            'http_errors' => false,
            'timeout' => 2,
        ]
    );
}

$typeMapper = new TypeMapper();
$client = DocumentClient::create($typeMapper, $httpClient);
$document = $client->get('https://cms.contentacms.io/api/recipes');
```

N.B. This example uses our [swisnl/php-http-fixture-client](https://github.com/swisnl/php-http-fixture-client) when in testing environment. This package allows you to easily mock requests with static fixtures. Definitely worth a try!

Using generics
--------------

[](#using-generics)

This package provides support for generic types in repositories and relationships, so your IDE can provide type hinting and auto-completion for the items you are working with.

This is achieved by using [generics in PHPDoc annotations](https://phpstan.org/blog/generics-in-php-using-phpdocs).

### Repositories

[](#repositories)

```
/** @extends \Swis\JsonApi\Client\Repository */
class BlogRepository extends \Swis\JsonApi\Client\Repository {...}
```

Now, when you use the `BlogRepository` class, your IDE understands the correct return types for the `all()`, `find()` and `save()` methods.

### Relationships

[](#relationships)

You can also use generics in your relationships to specify the type of the related item. Just use the `OneRelationInterface` or `ManyRelationInterface` interfaces in your relation method and specify the type of the related item:

```
/** @return \Swis\JsonApi\Client\Interfaces\OneRelationInterface */
public function author(): OneRelationInterface
{
    return $this->hasOne(AuthorItem::class);
}
```

This way, when accessing the `$blog->author()->getData()`, your IDE will understand that it returns an `AuthorItem` instance.

The same can be achieved for ManyRelations (`HasMany`, `MorphToMany`):

```
/** @return \Swis\JsonApi\Client\Interfaces\ManyRelationInterface */
public function comments(): ManyRelationInterface
{
    return $this->hasMany(CommentItem::class);
}
```

Advanced usage
--------------

[](#advanced-usage)

If you don't like to use the supplied repository or clients, you can also parse a 'raw' `\Psr\Http\Message\ResponseInterface` or a simple json string using the `Parsers\ResponseParser` or `Parser\DocumentParser` respectively.

Change log
----------

[](#change-log)

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

Testing
-------

[](#testing)

```
composer test
```

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

[](#contributing)

Please see [CONTRIBUTING](CONTRIBUTING.md) and [CODE\_OF\_CONDUCT](CODE_OF_CONDUCT.md) for details.

Security
--------

[](#security)

If you discover any security related issues, please email  instead of using the issue tracker.

License
-------

[](#license)

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

This package is [Treeware](https://treeware.earth). If you use it in production, then we ask that you [**buy the world a tree**](https://plant.treeware.earth/swisnl/json-api-client) to thank us for our work. By contributing to the Treeware forest you’ll be creating employment for local families and restoring wildlife habitats.

SWIS ❤️ Open Source
-------------------

[](#swis-heart-open-source)

[SWIS](https://www.swis.nl) is a web agency from Leiden, the Netherlands. We love working with open source software.

###  Health Score

68

—

FairBetter than 100% of packages

Maintenance86

Actively maintained with recent releases

Popularity54

Moderate usage in the ecosystem

Community33

Small or concentrated contributor base

Maturity83

Battle-tested with a long release history

 Bus Factor1

Top contributor holds 91.2% 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 ~48 days

Recently: every ~167 days

Total

65

Last Release

66d ago

Major Versions

0.20.0 → 1.0.0-beta2019-07-22

1.3.3 → 2.0.0-beta2021-07-01

1.x-dev → 2.0.02022-01-04

PHP version history (6 changes)0.0.2PHP &gt;=7.0

0.17.0PHP &gt;=7.1.3

2.0.0-betaPHP &gt;=7.2.5

2.0.0PHP ^7.3|^8.0

2.3.0PHP ^7.4|^8.0

2.5.0PHP ^8.0

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/8734305?v=4)[SWIS](/maintainers/swisnl)[@swisnl](https://github.com/swisnl)

---

Top Contributors

[![JaZo](https://avatars.githubusercontent.com/u/3475007?v=4)](https://github.com/JaZo "JaZo (457 commits)")[![bbrala](https://avatars.githubusercontent.com/u/3294970?v=4)](https://github.com/bbrala "bbrala (28 commits)")[![jely2002](https://avatars.githubusercontent.com/u/20154900?v=4)](https://github.com/jely2002 "jely2002 (4 commits)")[![laravel-shift](https://avatars.githubusercontent.com/u/15991828?v=4)](https://github.com/laravel-shift "laravel-shift (4 commits)")[![BurningDog](https://avatars.githubusercontent.com/u/787653?v=4)](https://github.com/BurningDog "BurningDog (3 commits)")[![Fivell](https://avatars.githubusercontent.com/u/120269?v=4)](https://github.com/Fivell "Fivell (1 commits)")[![karinarastsinskagia](https://avatars.githubusercontent.com/u/32904307?v=4)](https://github.com/karinarastsinskagia "karinarastsinskagia (1 commits)")[![rolfvandekrol](https://avatars.githubusercontent.com/u/434397?v=4)](https://github.com/rolfvandekrol "rolfvandekrol (1 commits)")[![rapkis](https://avatars.githubusercontent.com/u/25427665?v=4)](https://github.com/rapkis "rapkis (1 commits)")[![HendrikN](https://avatars.githubusercontent.com/u/850404?v=4)](https://github.com/HendrikN "HendrikN (1 commits)")

---

Tags

clienthacktoberfesthydrationjsonjson-apilaravel-inspiredpsr

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Code StyleLaravel Pint

Type Coverage Yes

### Embed Badge

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

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

###  Alternatives

[openai-php/client

OpenAI PHP is a supercharged PHP API client that allows you to interact with the Open AI API

5.8k22.6M232](/packages/openai-php-client)[getbrevo/brevo-php

Official Brevo provided RESTFul API V3 php library

963.1M35](/packages/getbrevo-brevo-php)[opensearch-project/opensearch-php

PHP Client for OpenSearch

15224.3M65](/packages/opensearch-project-opensearch-php)[phpro/http-tools

HTTP tools for developing more consistent HTTP implementations.

28137.8k](/packages/phpro-http-tools)[telnyx/telnyx-php

Official Telnyx PHP SDK — APIs for Voice, SMS, MMS, WhatsApp, Fax, SIP Trunking, Wireless IoT, Call Control, and more. Build global communications on Telnyx's private carrier-grade network.

35636.1k2](/packages/telnyx-telnyx-php)[mozex/anthropic-php

Anthropic PHP is a supercharged community-maintained PHP API client that allows you to interact with Anthropic API.

46365.1k13](/packages/mozex-anthropic-php)

PHPackages © 2026

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