Download the PHP package rickj/doctrine-rest-driver without Composer
On this page you can find all versions of the php package rickj/doctrine-rest-driver. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.
Download rickj/doctrine-rest-driver
More information about rickj/doctrine-rest-driver
Files in rickj/doctrine-rest-driver
Package doctrine-rest-driver
Short Description Use a REST API as if it was your local database
License proprietary
Informations about the package doctrine-rest-driver
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
- You need composer to download the library
Installation
Add the driver to your project using composer:
Change the following doctrine dbal configuration entries:
Additionally you can add CURL-specific options:
A full list of all possible options can be found here: http://php.net/manual/en/function.curl-setopt.php
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:
Usage
If your API routes follow these few conventions, using the driver is very easy:
- Each route must be structured the same:
- The PUT/PATCH, GET (single) and UPDATE routes need to contain an additional :
- POST and GET (all) must follow the basic structure:
Don't worry, if this is not the case: Luckily, we provide a few annotations for you to configure your own routes.
Responses
Your API is allowed to respond with a handful of different HTTP status codes to be deemed a successful response.
Method | "successful" status codes |
---|---|
GET | 200, 203, 206, 404 |
PUT/PATCH | 200, 202, 203, 204, 205, 404 |
POST | 200, 201, 202, 203, 204, 205 |
DELETE | 200, 202, 203, 204, 205, 404 |
Note 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
First of all create your entities:
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:
- UPDATE queries will be turned into PUT requests:
- Urls have the following format:
- The DELETE operation will remain:
- Urls have the following format:
- SELECT queries become GET requests:
- Urls have the following format: (if a single entity is requested) or (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 setting (chapter installation) with .
If your API doesn't follow our conventions
Now it's time to introduce you to some annotations, which help you to configure your own routes. Be sure to use them only with entities. All these annotations have the same structure so we will call them annotation:
The value is mandatory, method and statusCode are optional.
To demonstrate their capabilities, let's customize some parts of the previous chapter with the annotation:
If you have a list of acceptable status codes you can also pass an array to the option:
The annotations tell the driver to send the requests to the configured URLs for each custom configuration. If you just want to define a specific route for one method, you don't need to use all annotations provided. The act as a placeholder for the entity's identifier.
Pagination
Queries in Doctrine can be paginated using the OFFSET and LIMIT keywords. Pagination will be sent as request headers by default, but this can be configured to have pagination sent as query parameters:
This will convert to the following:
To:
The parameter keys used for per_page
and page
can also be set in the
configuration file:
Examples
Need some more examples? Here they are:
Persisting entities
Imagine you have a REST API at http://www.your-url.com/api:
Route | Method | Description | Payload | Response | Success HTTP Code | Error HTTP Code |
---|---|---|---|---|---|---|
/addresses | POST | persists addresses | UnregisteredAddress | RegisteredAddress | 200 | 400 |
Let's first configure Doctrine:
Afterwards let's build the address entity:
And finally the controller and its action:
That's it. Each time the createAction is called it will send a POST request to the API.
Associating entities
Let's extend the first example. Now we want to add a new entity type which references the addresses defined in the previous example.
The REST API offers the following additional routes:
Route | Method | Description | Payload | Response |
---|---|---|---|---|
/users | POST | persists a new user | UnregisteredUser | RegisteredUser |
/addresses | POST | persists a new address | UnregisteredAddress | RegisteredAddress |
/addresses/\<id> | GET | returns one address | NULL | RegisteredAddress |
First, we need to build an additional entity "User":
The user has a relation to address. So let's have a look at what happens if we associate them:
If we'd set name to , password to and addressId to by triggering the createAction, the following requests would be sent by our driver:
Because we have used the option on the relation between users and addresses DELETE requests for addresses are automatically sent if the owning user is removed:
For example, a DELETE request with the id would trigger these requests:
Great, isn't it?
Using multiple Backends
In this last example we split the user and the address routes into two different REST APIs. This means we need multiple managers which is explained in the Doctrine documentation:
Now it's getting crazy: We will try to read data from two different APIs and persist them into a MySQL database. Imagine the user API with the following route:
Route | Method | Description | Payload | Response |
---|---|---|---|---|
/users/\<id> | GET | returns one user | NULL | RegisteredUser |
and the address API with this entry point:
Route | Method | Description | Payload | Response |
---|---|---|---|---|
/addresses/\<id> | GET | returns one address | NULL | RegisteredAddress |
We want to read a user from the user API and an address from the address API. After that we will associate and persist them in our MySQL database.
As you can see in the request log both APIs are requested:
Afterwards both entities are persisted in the default MySQL database.
Testing
To test the bundle just type:
Contributing
If you want to contribute to this repository, please ensure ...
- to follow the existing coding style.
- to use the linting tools that are listed in the (which you get for free when using ).
- to add and/or customize unit tests for any changed code.
- to reference the corresponding issue in your pull request with a small description of your changes.
All contributors are listed in the file, sorted by the time of their first contribution.
All versions of doctrine-rest-driver with dependencies
doctrine/dbal Version 2.*
greenlion/php-sql-parser Version ^4.0
doctrine/orm Version 2.*
rickj/restclientbundle Version ^2.0.2