PHPackages                             skqr/hateoas - 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. skqr/hateoas

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

skqr/hateoas
============

GOintegro HATEOAS Lib

v0.10.14(9y ago)08511MITPHPPHP &gt;=5.4.0

Since Dec 5Pushed 9y ago1 watchersCompare

[ Source](https://github.com/skqr/hateoas)[ Packagist](https://packagist.org/packages/skqr/hateoas)[ Docs](http://www.gointegro.com)[ RSS](/packages/skqr-hateoas/feed)WikiDiscussions develop Synced 1mo ago

READMEChangelogDependencies (20)Versions (30)Used By (1)

[GOintegro](http://www.gointegro.com/en/) / HATEOAS
===================================================

[](#gointegro--hateoas)

[![Join the chat at https://gitter.im/skqr/hateoas](https://camo.githubusercontent.com/abe08b740a4156153736f791393ec4da6619c4be73212e75769f52edacc0e2b5/68747470733a2f2f6261646765732e6769747465722e696d2f4a6f696e253230436861742e737667)](https://gitter.im/skqr/hateoas?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)

[![Build Status](https://camo.githubusercontent.com/f841652009734e33ec62417e064377a4b084a31a7340023a75ee842f25b71fdf/68747470733a2f2f7472617669732d63692e6f72672f736b71722f686174656f61732e7376673f6272616e63683d6d6173746572)](https://travis-ci.org/skqr/hateoas) [![Code Climate](https://camo.githubusercontent.com/7101507ba0bae616d4913f19008cb166eb4a87c48587132772445b7193d1794f/68747470733a2f2f636f6465636c696d6174652e636f6d2f6769746875622f736b71722f686174656f61732f6261646765732f6770612e737667)](https://codeclimate.com/github/skqr/hateoas)

This is a library that uses a Doctrine 2 entity map and a [RAML](http://raml.org/) API definition to conjure a [HATEOAS](http://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm) API, following the [JSON-API](http://jsonapi.org/) specification.

You don't get scaffolds. You get a working API.

You get a working API with features sweeter than [a Bobcat's self-esteem](http://s3.amazonaws.com/theoatmeal-img/comics/bobcats_thursday/mirror.png).

Features
--------

[](#features)

Here's what I mean.

- Flat, referenced JSON serialization.
    - Clear distinction between scalar fields and linked resources.
- Magic controllers.
    - Fetching resources, with support for:
        - Sparse fields;
        - Linked resources expansion;
        - [Standarized filtering](#query-filters) and sorting;
        - Pagination;
        - Resource metadata, such as facets in a search.
    - Altering resources, with support for:
        - Processing multiple actions in one request;
        - Request validation using JSON schema;
        - [Entity validation](#validation) using Symfony's validator;
        - [Create, update, and delete](#creating-updating-and-deleting) out of the box;
        - Assign services to handle any of the above for specific resources.
- [Translatable content](#translatable-content) out-of-the-box.
- [Metadata caching](#caching), similar to that of Doctrine 2;
    - Redis,
    - Or Memcached.

Here's what you'll need.

- A Doctrine 2 entity map;
- A RAML API definition;
- At least one Symfony 2 security voter.

Try it out
==========

[](#try-it-out)

Check out [the example app project](https://github.com/skqr/hateoas-bundle-example), so you can feel the magic in your finger tips without much ado.

---

Installation
============

[](#installation)

Check out the [Symfony 2 bundle](https://github.com/skqr/hateoas-bundle/) for a full-stack framework implementation.

---

Usage
=====

[](#usage)

Design your API in [the RAML language](http://raml.org/docs.html) following [the JSON-API spec](http://jsonapi.org/format/#document-structure-resource-urls).

Something like this example, which assumes you have an entity class with the short-name `User`.

```
#%RAML 0.8
title: HATEOAS Inc. Example API
version: v1
baseUri: http://localhost:8000/api/{version}
mediaType: application/vnd.api+json
/users:
  get:
    description: Fetches all users.
    responses:
      200:
  post:
    description: Creates one or more users.
    responses:
      201:
  /{user-ids}:
    get:
      description: Fetches users by Id.
      responses:
        200:
    put:
      description: Updates one or more users by Id.
      responses:
        200:
    delete:
      description: Deletes one or more users by Id.
    /links:
      /{relationship}:
        get:
          description: Fetches the related resources.
          responses:
            200:
        post:
          description: Relates one or more resources.
          responses:
            201:
        put:
          description: Updates the relationship.
          responses:
            204:
        delete:
          description: Removes the relationship.
        /{relationship-ids}:
          delete:
            description: Removes to-many relationships by Id.
```

Have your entity implement the resource interface.

The namespace isn't considered, only the short-name is used to match against the resources defined above.

```

```

Voilà - you get the following for free.

```
GET /users
GET /users/1
GET /users/1,2,3
GET /users/1/name
GET /users/1/linked/posts
GET /posts/1/linked/owner
GET /posts?owner=1
GET /posts?owner=1,2,3
GET /users?sort=name,-birth-date
GET /users?include=posts,posts.comments
GET /users?fields=name,email
GET /users?include=posts,posts.comments&fields[users]=name&fields[posts]=content
GET /users?page=1
GET /users?page=1&size=10

```

Any combination.

You also get these.

```
POST /users

PUT /users/1
PUT /users/1,2,3

DELETE /users/1
DELETE /users/1,2,3

```

And you get to link or unlink resources thus.

```
POST /users/1/links/user-groups

PUT /users/1/links/user-groups

DELETE /users/1/links/user-groups
DELETE /users/1/links/user-groups/1
DELETE /users/1/links/user-groups/1,2,3

```

Sweet, right?

> The `resource_type` **must** match the calculated type - for now. E.g. `UserGroup`, `user-groups`.

Resources
=========

[](#resources)

But you need to have some control over what you expose, right? Got you covered.

You can optionally define a class like this for your entity, and optionally define any of the properties and methods you will see within.

```
