Baike.dev
All toolsOnline toolsAI codingTrendingOpen sourceNewsSubmit
Log in
< Back to tools
H

Hateoas

> 编程语言
Open source

A PHP library to support implementing representations for HATEOAS REST web services.

1.0K stars0 likes2 views
WebsiteGitHub

About

A PHP library to support implementing representations for HATEOAS REST web services.

Hateoas

A PHP library to support implementing representations for HATEOAS REST web services.

  • Installation
    • Working With Symfony
  • Usage
    • Introduction
    • Configuring Links
    • Embedding Resources
    • Dealing With Collections
    • Representations
      • VndErrorRepresentation
    • The Expression Language
      • Context
      • Adding Your Own Context Variables
      • Expression Functions
    • URL Generators
    • Helpers
      • LinkHelper
    • Twig Extensions
      • LinkExtension
    • Serializers & Formats
      • The JsonHalSerializer
      • The XmlSerializer
      • The XmlHalSerializer
      • Adding New Serializers
    • The HateoasBuilder
      • XML Serializer
      • JSON Serializer
      • URL Generator
      • Expression Evaluator/Expression Language
      • Relation Provider
      • (JMS) Serializer Specific
      • Others
    • Configuring a Cache Directory
    • Configuring Metadata Locations
    • Extending The Library
  • Reference
    • XML
    • YAML
    • Annotations/Attributes
      • @Relation
      • @Route
      • @Embedded
      • @Exclusion
      • @RelationProvider
  • Internals
  • Versioning

Installation

The recommended way to install Hateoas is through Composer. Require the willdurand/hateoas package by running the following command:

bash
composer require willdurand/hateoas

This will resolve the latest stable version.

Otherwise, install the library and setup the autoloader yourself.

If you want to use annotations for configuration you need to install the doctrine/annotations package:

bash
composer require doctrine/annotations

If your app uses PHP 8.1 or higher it is recommended to use native PHP attributes. In this case you don't need to install the Doctrine package.

Working With Symfony

There is a bundle for that! Install the BazingaHateoasBundle, and enjoy!

Usage

Important:

For those who use the 1.0 version, you can jump to this documentation page.

For those who use the 2.0 version, you can jump to this documentation page.

The following documentation has been written for Hateoas 3.0 and above.

Introduction

Hateoas leverages the Serializer library to provide a nice way to build HATEOAS REST web services. HATEOAS stands for Hypermedia as the Engine of Application State, and adds hypermedia links to your representations (i.e. your API responses). HATEOAS is about the discoverability of actions on a resource.

For instance, let's say you have a User API which returns a representation of a single user as follow:

json
{
    "user": {
        "id": 123,
        "first_name": "John",
        "last_name": "Doe"
    }
}

In order to tell your API consumers how to retrieve the data for this specific user, you have to add your very first link to this representation, let's call it self as it is the URI for this particular user:

json
{
    "user": {
        "id": 123,
        "first_name": "John",
        "last_name": "Doe",
        "_links": {
            "self": { "href": "http://example.com/api/users/123" }
        }
    }
}

Let's dig into Hateoas now.

Configuring Links

In Hateoas terminology, links are seen as relations added to resources. It is worth mentioning that relations also refer to embedded resources too, but this topic will be covered in the Embedding Resources section.

A link is a relation which is identified by a name (e.g. self) and that has an href parameter:

Annotation (PHP

php
use JMS\Serializer\Annotation as Serializer;
use Hateoas\Configuration\Annotation as Hateoas;

/**
* @Serializer\XmlRoot("user")
*
* @Hateoas\Relation("self", href = "expr('/api/users/' ~ object.getId())")
*/
class User
{
    /** @Serializer\XmlAttribute */
    private $id;
    private $firstName;
    private $lastName;

    public function getId() {}
}

Attribute (PHP 8.1 and greater)

php
use JMS\Serializer\Annotation as Serializer;
use Hateoas\Configuration\Annotation as Hateoas;

#[Serializer\XmlRoot('user')]
#[Hateoas\Relation('self', href: "expr('/api/users/' ~ object.getId())")]
class User
{
    #[Serializer\XmlAttribute]
    private $id;
    private $firstName;
    private $lastName;

    public function getId() {}
}

In the example above, we configure a self relation that is a link because of the href parameter. Its value, which may look weird at first glance, will be extensively covered in The Expression Language section. This special value is used to generate a URI.

In this section, annotations/attributes are used to configure Hateoas. XML and YAML formats are also supported. If you wish, you can use plain PHP too.

Important: you must configure both the Serializer and Hateoas the same way. E.g. if you use YAML for configuring Serializer, use YAML for configuring Hateoas.

The easiest way to try HATEOAS is with the HateoasBuilder. The builder has numerous methods to configure the Hateoas serializer, but we won't dig into them right now (see The HateoasBuilder). Everything works fine out of the box:

php
use Hateoas\HateoasBuilder;

$hateoas = HateoasBuilder::create()->build();

$user = new User(42, 'Adrien', 'Brault');
$json = $hateoas->serialize($user, 'json');
$xml  = $hateoas->serialize($user, 'xml');

The $hateoas object is an instance of JMS\Serializer\SerializerInterface, coming from the Serializer library. Hateoas does not come with its own serializer, it hooks into the JMS Serializer.

By default, Hateoas uses the Hypertext Application Language (HAL) for JSON serialization. This specifies the structure of the response (e.g. that "links" should live under a _links key):

json
{
    "id": 42,
    "first_name": "Adrien",
    "last_name": "Brault",
    "_links": {
        "self": {
            "href": "/api/users/42"
        }
    }
}

For XML, Atom Links are used by default:

xml

    
    
    

It is worth mentioning that these formats are the default ones, not the only available ones. You can use different formats through different serializers, and even add your owns.

Now that you know how to add links, let's see how to add embedded resources.

Embedding Resources

Sometimes, it's more efficient to embed related resources rather than link to them, as it prevents clients from having to make extra requests to fetch those resources.

An embedded resource is a named relation that contains data, represented by the embedded parameter.

Annotation (PHP

php
use JMS\Serializer\Annotation as Serializer;
use Hateoas\Configuration\Annotation as Hateoas;

/**
 * ...
 *
 * @Hateoas\Relation(
 *     "manager",
 *     href = "expr('/api/users/' ~ object.getManager().getId())",
 *     embedded = "expr(object.getManager())",
 *     exclusion = @Hateoas\Exclusion(excludeIf = "expr(object.getManager() === null)")
 * )
 */
class User
{
    ...

    /** @Serializer\Exclude */
    private $manager;
}

Attribute (PHP 8.1 and greater)

php
use JMS\Serializer\Annotation as Serializer;
use Hateoas\Configuration\Annotation as Hateoas;

#[Hateoas\Relation(
     'manager',
     href: "expr('/api/users/' ~ object.getManager().getId())",
     embedded: "expr(object.getManager())",
     exclusion: new Hateoas\Exclusion(excludeif: "expr(object.getManager() === null)"),
 )]
class User
{
    ...

    #[Serializer\Exclude]
    private $manager;
}

Note: You will need to exclude the manager property from the serialization, otherwise both the serializer and Hateoas will serialize it. You will also have to exclude the manager relation when the manager is null, because otherwise an error will occur when creating the href link (calling getId() on null).

Tip: If the manager property is an object that already has a _self link, you can re-use that value for the href instead of repeating it here. See LinkHelper.

php
$hateoas = HateoasBuilder::create()->build();

$user = new User(42, 'Adrien', 'Brault', new User(23, 'Will', 'Durand'));
$json = $hateoas->serialize($user, 'json');
$xml  = $hateoas->serialize($user, 'xml');

For json, the HAL representation places these embedded relations inside an _embedded key:

json
{
    "id": 42,
    "first_name": "Adrien",
    "last_name": "Brault",
    "_links": {
        "self": {
            "href": "/api/users/42"
        },
        "manager": {
            "href": "/api/users/23"
        }
    },
    "_embedded": {
        "manager": {
            "id": 23,
            "first_name": "Will",
            "last_name": "Durand",
            "_links": {
                "self": {
                    "href": "/api/users/23"
                }
            }
        }
    }
}

In XML, serializing embedded relations will create new elements:

xml

    
    
    
    
    
        
        
        
    

The tag name of an embedded resource is inferred from the @XmlRoot annotation (xml_root_name in YAML, xml-root-name in XML) coming from the Serializer configuration.

Dealing With Collections

The library provides several classes in the Hateoas\Representation\* namespace to help you with common tasks. These are simple classes configured with the library's annotations.

The PaginatedRepresentation, OffsetRepresentation and CollectionRepresentation classes are probably the most interesting ones. These are helpful when your resource is actually a collection of resources (e.g. /users is a collection of users). These help you represent the collection and add pagination and limits:

…

The CollectionRepresentation offers a basic representation of an embedded collection.

The PaginatedRepresentation is designed to add self, first, and when possible last, next, and previous links.

The OffsetRepresentation works just like PaginatedRepresentation but is useful when pagination is expressed by offset, limit and total.

The RouteAwareRepresentation adds a self relation based on a given route.

You can generate absolute URIs by setting the absolute parameter to true in both the PaginatedRepresentation and the RouteAwareRepresentation.

The Hateoas library also provides a PagerfantaFactory to easily build PaginatedRepresentation from a Pagerfanta instance. If you use the Pagerfanta library, this is an easier way to create the collection represent

Issues· 0 open

View all issuesOpen on GitHub

No open issues yet, or sync has not completed.

> Tags

PHPhateoasjsonphprest

No comments yet. Be the first to share.

> Details

PublishedAug 1, 2026
UpdatedSep 17, 2026
Category编程语言
PricingOpen source

> Related tools

T
TypeScript
JavaScript 的超集,为前端与全栈提供静态类型
P
Python
通用编程语言,广泛用于 Web、数据与 AI
G
Go
Google 推出的简洁高效系统语言