PHPackages                             circle/doctrine-rest-driver - 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. [Database &amp; ORM](/categories/database)
4. /
5. circle/doctrine-rest-driver

ActiveLibrary[Database &amp; ORM](/categories/database)

circle/doctrine-rest-driver
===========================

Use a REST API as if it was your local database

1.3.6(6y ago)15634.5k39[14 issues](https://github.com/CircleOfNice/DoctrineRestDriver/issues)[2 PRs](https://github.com/CircleOfNice/DoctrineRestDriver/pulls)GPLPHPPHP &gt;=5.5

Since Mar 27Pushed 1y ago14 watchersCompare

[ Source](https://github.com/CircleOfNice/DoctrineRestDriver)[ Packagist](https://packagist.org/packages/circle/doctrine-rest-driver)[ RSS](/packages/circle-doctrine-rest-driver/feed)WikiDiscussions master Synced 1mo ago

READMEChangelog (10)Dependencies (12)Versions (29)Used By (0)

Motivation
==========

[](#motivation)

What does a black sheep and a white sheep have in common? They produce wool.
What does a big bus and a small bus have in common? They drive people around.
And what does a SQL database and a REST API have in common? They store data.

As blatantly obvious as this sounds the consequences are tremendous: With REST APIs being nothing more than data storage backends, we are able to reuse object relational mapping tools to access them.

And because we have absolutely no idea how to write a programming language, we're tryin to do it like Rasmus and keep adding the next logical step on the way. So DoctrineRestDriver saw the light of day.

Prerequisites
=============

[](#prerequisites)

- You need composer to download the library

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

[](#installation)

Add the driver to your project using composer:

```
composer require circle/doctrine-rest-driver
```

Change the following doctrine dbal configuration entries:

```
doctrine:
  dbal:
    driver_class: "Circle\\DoctrineRestDriver\\Driver"
    host:         "%default_api_url%"
    port:         "%default_api_port%"
    user:         "%default_api_username%"
    password:     "%default_api_password%"
    options:
      format:               "json" | "YourOwnNamespaceName" | if not specified json will be used
      authenticator_class:  "HttpAuthentication" | "YourOwnNamespaceName" | if not specified no authentication will be used
```

Additionally you can add CURL-specific options:

```
doctrine:
  dbal:
    driver_class: "Circle\\DoctrineRestDriver\\Driver"
    host:         "%default_api_url%"
    port:         "%default_api_port%"
    user:         "%default_api_username%"
    password:     "%default_api_password%"
    options:
      format:                         "json"
      authenticator_class:            "HttpAuthentication"
      CURLOPT_CURLOPT_FOLLOWLOCATION: true
      CURLOPT_HEADER:                 true
```

A full list of all possible options can be found here:

By default, UPDATE queries are converted to PUT to work with the majority of APIs however, when persisting an updated entity, Doctrine will compare the edited entity to the original data and create a query that only contains the changed fields. In a REST API, this would be converted to a PATCH request as a PUT is meant to include the entire entity even if some properties have not changed.

To use PATCH instead of PUT simply add a config value:

```
doctrine:
  dbal:
    options:
      use_patch: true
```

Usage
=====

[](#usage)

If your API routes follow these few conventions, using the driver is very easy:

- Each route must be structured the same: `{apiHost}/{pathToApi}/{tableName}`
- The PUT/PATCH, GET (single) and UPDATE routes need to contain an additional `id`: `{apiHost}/{pathToApi}/{tableName}/{id}`
- POST and GET (all) must follow the basic structure: `{apiHost}/{pathToApi}/{tableName}`

Don't worry, if this is not the case: Luckily, we provide a few annotations for you to configure your own routes.

Responses
---------

[](#responses)

Your API is allowed to respond with a handful of different HTTP status codes to be deemed a successful response.

Method"successful" status codesGET200, 203, 206, 404PUT/PATCH200, 202, 203, 204, 205, 404POST200, 201, 202, 203, 204, 205DELETE200, 202, 203, 204, 205, 404Note that a 404 response is considered a "successful" response in some circumstances. This allows the driver to reflect a database being queried but returning no data due to an entity not being found, for example "/entity/1" will allow a 404 without causing an exception as it's perfectly acceptable to not find an entity from a database.

The examples below show how to use the driver in a Symfony environment.

If your API follows our conventions
-----------------------------------

[](#if-your-api-follows-our-conventions)

First of all create your entities:

```
namespace CircleBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * This annotation marks the class as managed entity:
 *
 * @ORM\Entity
 * @ORM\Table("products")
 */
class Product {

    /**
     * @ORM\Column(type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @ORM\Column(type="string", length=100)
     */
    private $name;

    public function getId() {
        return $this->id;
    }

    public function setName($name) {
        $this->name = $name;
        return $this;
    }

    public function getName() {
        return $this->name;
    }
}
```

Afterwards, you are able to use the created entity as if you were using a database.

By using this setting, the driver is performing a lot of magic under the hood:

- It generally uses the request body to send data in JSON format
- It automatically maps the response into a valid entity if the status code matches the default expected status codes (200 for GET and PUT, 201 for POST 204 for DELETE)
- It saves the entity as managed doctrine entity
- It translates INSERT queries into POST requests to create new data
    - Urls have the following format: `{apiHost}/{pathToApi}/{tableName}`
- UPDATE queries will be turned into PUT requests:
    - Urls have the following format: `{apiHost}/{pathToApi}/{tableName}/{id}`
- The DELETE operation will remain:
    - Urls have the following format: `{apiHost}/{pathToApi}/{tableName}/{id}`
- SELECT queries become GET requests:
    - Urls have the following format: `{apiHost}/{pathToApi}/{tableName}/{id}` (if a single entity is requested) or `{apiHost}/{pathToApi}/{tableName}` (if all entities are requested)

Let's watch the driver in action by implementing some controller methods. In this example we assume that we have configured the `host` setting [(chapter installation)](#installation) with `http://www.yourSite.com/api`.

```
