Flag of Ukraine
SymfonyCasts stands united with the people of Ukraine
This tutorial has a new version, check it out!

HATEOAS & Hypermedia: The Buzzwords Level

Keep on Learning!

If you liked what you've learned so far, dive in!
Subscribe to get access to this tutorial plus
video, code and script downloads.

Start your All-Access Pass
Buy just this tutorial for $12.00

With a Subscription, click any sentence in the script to jump to that part of the video!

Login Subscribe

These days, you expect a tutorial on REST to immediately throw out some buzzwords: like hypermedia and HATEOAS. But I've tried not to mention these because honestly, in practice: they're more trouble than good.

But, there are some cool parts! It's time to learn what these mean, what parts are good, and what parts almost drove me to drinking.

Hypermedia: Really Caffeinated DVD's

First, hypermedia! This does not involve slamming red bulls and binge-watching Netflix. Here's the story: JSON is known as a media type. If I tell you that I'm giving you a JSON string, you understand how to parse it. XML is another media type: if I give you XML, you can understand its format.

The difference between media and hypermedia is that hypermedia is a format that includes links. For example, if you used a JSON structure that consistently put links under a _links key, well, you could claim that you just created your own hypermedia format: a JSON structure where I know - semantically - what _links means: it's not data: it's links to other resources.

The most famous hypermedia format is ... drumroll HTML! It's basically an XML media type that has built-in tags for links: the <a> tag. Actually, <form>, <img> <link> and <script> are also considered "links" to other resources.

So calling something a hypermedia format is just a way of saying:

Hey, when we return the JSON data, what if we added some rules that say any links we want to include always live in the same place?

And even though I avoided the word - hypermedia - in a sense, we're already returning a hypermedia format because we always include links under an _links key. We'll talk more about this a little later: there are actually "official" hypermedia formats you can adopt for your API.

HATEOAS

Ready for buzzword #2? HATEOAS... or HAT-E-OAS... or H-ATE-OAS... nobody really knows how to say it. Anyways, the throat-clearing acronym stands for:

Hypermedia As The Engine Of Application State

Whoa. Let's unpack that monster. It's actually a cool idea.

Application state refers to which endpoint a client is currently using. As the client does more things - like creating a programmer and then starting a battle - they're moving through different "application" states, the same way that someone moves through the pages on your web site.

Normally, the client figures out which endpoint - or state - they need next by reading some API documentation. But HATEOAS says:

What if we didn't write API documentation and instead, every response we send back self-documents what endpoints you might want next via links?

So when we send back a programmer resource, it would contain a link for every other possible thing the client might want to do next - like starting a battle with that programmer.

In an ideal world, you would stop writing documentation and just say:

Hey, use my API! Every time you make a request, I'll include details about what do to next.

In reality, HATEOAS is a fantasy, at least for now. For it to work, links would need to be able to contain what HTTP method to use, what fields to send, and what those fields mean. It's hard, way too hard for most people right now, including me.

Here's the right way to navigate this mine field. Instead of saying:

I'm going to include so many links that I don't have to document anything!

You should say:

I'm going to add links that might be helpful, but also write documentation.

So let's do that: and take this idea in our app up to a new level.

Leave a comment!

0
Login or Register to join the conversation
Cat in space

"Houston: no signs of life"
Start the conversation!

This tutorial uses an older version of Symfony. The concepts of Hypermedia & HATEOAS are still valid. But I recommend using API Platform in modern Symfony apps.

What PHP libraries does this tutorial use?

// composer.json
{
    "require": {
        "php": ">=5.5.9",
        "symfony/symfony": "3.0.*", // v3.0.3
        "doctrine/orm": "^2.5", // v2.5.4
        "doctrine/doctrine-bundle": "^1.6", // 1.6.2
        "doctrine/doctrine-cache-bundle": "^1.2", // 1.3.0
        "symfony/swiftmailer-bundle": "^2.3", // v2.3.11
        "symfony/monolog-bundle": "^2.8", // v2.10.0
        "sensio/distribution-bundle": "^5.0", // v5.0.4
        "sensio/framework-extra-bundle": "^3.0.2", // v3.0.14
        "incenteev/composer-parameter-handler": "~2.0", // v2.1.2
        "jms/serializer-bundle": "^1.1.0", // 1.1.0
        "white-october/pagerfanta-bundle": "^1.0", // v1.0.5
        "lexik/jwt-authentication-bundle": "^1.4", // v1.4.3
        "willdurand/hateoas-bundle": "^1.1" // 1.1.1
    },
    "require-dev": {
        "sensio/generator-bundle": "^3.0", // v3.0.6
        "symfony/phpunit-bridge": "^3.0", // v3.0.3
        "behat/behat": "~3.1@dev", // dev-master
        "behat/mink-extension": "~2.2.0", // v2.2
        "behat/mink-goutte-driver": "~1.2.0", // v1.2.1
        "behat/mink-selenium2-driver": "~1.3.0", // v1.3.1
        "phpunit/phpunit": "~4.6.0", // 4.6.10
        "doctrine/doctrine-fixtures-bundle": "^2.3" // 2.3.0
    }
}
userVoice