PHPackages                             aeq/hal - 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. aeq/hal

ActiveLibrary[API Development](/categories/api)

aeq/hal
=======

1.0.2(9y ago)214.4kPHPPHP &gt;=5.5.0

Since Apr 18Pushed 9y ago2 watchersCompare

[ Source](https://github.com/kschu91/hal)[ Packagist](https://packagist.org/packages/aeq/hal)[ RSS](/packages/aeq-hal/feed)WikiDiscussions master Synced 1mo ago

READMEChangelog (7)Dependencies (4)Versions (8)Used By (0)

\#PHP HAL (Hypertext Application Language) Explorer#

[![Build Status](https://camo.githubusercontent.com/8cde63b58514f313c95cf5edcdc29d2c95248226745f701154f2d2c19e8f540f/68747470733a2f2f7472617669732d63692e6f72672f6b7363687539312f68616c2e7376673f6272616e63683d6d6173746572)](https://travis-ci.org/kschu91/hal)[![Code Coverage](https://camo.githubusercontent.com/261a42d241f127932be788c5a14b9f8213f7e7ddc32a211651cb7f00309b84e1/68747470733a2f2f7363727574696e697a65722d63692e636f6d2f672f6b7363687539312f68616c2f6261646765732f636f7665726167652e706e673f623d6d6173746572)](https://scrutinizer-ci.com/g/kschu91/hal/?branch=master)[![Scrutinizer Code Quality](https://camo.githubusercontent.com/b1ad07fa37827d9ea55510f054d765f57a80bc265637806a4e4760c7b4c55011/68747470733a2f2f7363727574696e697a65722d63692e636f6d2f672f6b7363687539312f68616c2f6261646765732f7175616c6974792d73636f72652e706e673f623d6d6173746572)](https://scrutinizer-ci.com/g/kschu91/hal/?branch=master)

This library provides a full featured API to discover a [HAL (Hypertext Application Language)](http://stateless.co/hal_specification.html) API via an expressive interface.

```
$posts = $resource->getLink('posts')->follow();
```

Features

- GuzzleHttp as default HTTP Client
- integrate custom HTTP clients easily
- human readable API
- Shipped with a simple default serializer for JSON responses
- Possibility to integrate custom serializers
- Fully tested
- Used in production projects

\##Usage##

\###1. Initiate the Explorer###

```
$explorer = new Explorer();
$explorer->setClientAdapter(new GuzzleClientAdapter(new Client()));
$explorer->setSerializer(new JsonSerializer());
```

If you want to use the the build in "GuzzleClientAdapter" you have to require guzzlehttp/guzzle manually in your composer project since guzzle is only suggested.

\###2. Request your API###

```
$response = $explorer->request('GET', '/my/api/');
```

\###3. Explore the response###

```
$resource = $explorer->explore($response);
```

\###4. Discover your API###

```
$posts = $resource->getLink('posts')->follow();
foreach($posts as $post) {
    $publisher = $post->getLink('publisher')->follow();
    $company = $publisher->getLink('company')->follow();
}
```

The result of following a link is that the resolved resource is appended to the parent „$resource“ object („\_embedded“). This allows you to access the linked resource without resolving the link again:

```
$posts = $resource->getEmbedded('posts');
foreach($posts as $post) {
    $publisher = $post->getEmbedded('publisher');
    $company = $publisher->getEmbedded('company');
}
```

\##Custom HTTP Clients## Create a new class implementing the "ClientAdapterInterface" and return the response as PSR-7.

```
use Aeq\Hal\Client\ClientAdapterInterface;

class MyCustomClientAdapter implements ClientAdapterInterface
{
    public function request($method, $uri = null, array $options = [])
    {
        // call your custom client and return the response
    }
}
```

Set the custom client adapter to your explorer before using it.

```
$explorer->setClientAdapter(new MyCustomClientAdapter());
```

\##Custom Serializers## Create a new class implementing the "SerializerInterface" and return the response.

```
use Aeq\Hal\Serializer\SerializerInterface;

class MyCustomSerializer implements SerializerInterface
{
    public function serialize($data)
    {
        // serialize your data: $data
    }

    public function deserialize($str)
    {
        // deserialize the string: $str
    }
}
```

Set the custom serializer to your explorer before using it.

```
$explorer->setSerializer(new MyCustomSerializer());
```

\##Events## This library offers you some events to listen on. To use the event system you have to add the "EventManager" to your Explorer before using it.

```
$explorer->setEventManager(new EventManager());
```

To listen on a specific event you have to implement a Listener. A Listener is a PHP object with a public method "handle". As parameter your will get the triggered Event object.

```
class MyHandler
{
    public function handle(EventInterface $event)
    {
        // process your stuff
    }
}
```

\###PostClientRequestEvent### This event is called on each executed request (after following a link or using the "request" method) and contains the complete PSR-7 response.

```
$explorer->listenOnEvent(PostClientRequestEvent::class, new MyHandler());
```

###  Health Score

32

—

LowBetter than 72% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity22

Limited adoption so far

Community8

Small or concentrated contributor base

Maturity63

Established project with proven stability

 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

Every ~34 days

Recently: every ~17 days

Total

7

Last Release

3471d ago

Major Versions

0.0.4 → 1.0.02016-11-02

### Community

Maintainers

![](https://www.gravatar.com/avatar/16a030944fdb6c9508d602db24db8f25023b76393295a19d206e586e686611b8?d=identicon)[kschu91](/maintainers/kschu91)

---

Top Contributors

[![kschu91](https://avatars.githubusercontent.com/u/5566756?v=4)](https://github.com/kschu91 "kschu91 (22 commits)")

###  Code Quality

TestsPHPUnit

Code StylePHP\_CodeSniffer

### Embed Badge

![Health badge](/badges/aeq-hal/health.svg)

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

###  Alternatives

[algolia/algoliasearch-client-php

API powering the features of Algolia.

69333.0M114](/packages/algolia-algoliasearch-client-php)[swisnl/json-api-client

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

211473.2k12](/packages/swisnl-json-api-client)[php-heroku-client/php-heroku-client

A PHP client for the Heroku Platform API

24404.8k4](/packages/php-heroku-client-php-heroku-client)[yoti/yoti-php-sdk

Yoti SDK for quickly integrating your PHP backend with Yoti

27539.9k1](/packages/yoti-yoti-php-sdk)[trycourier/courier

Courier PHP SDK

16643.9k](/packages/trycourier-courier)[commercetools/commercetools-sdk

The official PHP SDK for the commercetools Composable Commerce APIs

19281.5k](/packages/commercetools-commercetools-sdk)

PHPackages © 2026

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