This library provides a GraphQL driver for Doctrine ORM for use with the webonyx/graphql-php library. It does not try to redefine how that excellent library operates. Instead, it creates types to be used within the framework that library provides.
Via composer:
composer require api-skeletons/doctrine-orm-graphql
Full documentation is available at https://doctrine-orm-graphql.apiskeletons.dev or in the docs directory.
- 12.x - Supports league/event version 3.0 and is PSR-14 compliant
- 11.x - Supports league/event version 2.2
More information in the documentation.
The LDOG Stack: Laravel, Doctrine ORM, and GraphQL uses this library: https://ldog.apiskeletons.dev
For an working implementation see https://graphql.lcdb.org and the corresonding application at https://github.com/lcdborg/graphql.lcdb.org.
- Supports all Doctrine Types and allows custom types
- Pagination with the GraphQL Complete Connection Model
- Filtering of sub-collections
- Events for modifying queries, entity types and more
- Multiple configuration group support
Add attributes to your Doctrine entities or see globalEnable for all entities in your schema without attribute configuration.
use ApiSkeletons\Doctrine\ORM\GraphQL\Attribute as GraphQL;
#[GraphQL\Entity]
class Artist
{
#[GraphQL\Field]
public $id;
#[GraphQL\Field]
public $name;
#[GraphQL\Association]
public $performances;
}
#[GraphQL\Entity]
class Performance
{
#[GraphQL\Field]
public $id;
#[GraphQL\Field]
public $venue;
/**
* Not all fields need attributes.
* Only add attribues to fields you want available in GraphQL
*/
public $city;
}
Create the driver and GraphQL schema
use ApiSkeletons\Doctrine\ORM\GraphQL\Driver;
use Doctrine\ORM\EntityManager;
use GraphQL\Type\Definition\ObjectType;
use GraphQL\Type\Definition\Type;
use GraphQL\Type\Schema;
$driver = new Driver($entityManager);
$schema = new Schema([
'query' => new ObjectType([
'name' => 'query',
'fields' => [
'artists' => $driver->completeConnection(Artist::class),
],
]),
'mutation' => new ObjectType([
'name' => 'mutation',
'fields' => [
'artistUpdateName' => [
'type' => $driver->type(Artist::class),
'args' => [
'id' => Type::nonNull(Type::id()),
'input' => Type::nonNull($driver->input(Artist::class, ['name'])),
],
'resolve' => function ($root, $args) use ($driver): Artist {
$artist = $driver->get(EntityManager::class)
->getRepository(Artist::class)
->find($args['id']);
$artist->setName($args['input']['name']);
$driver->get(EntityManager::class)->flush();
return $artist;
},
],
],
]),
]);
Run GraphQL queries
use GraphQL\GraphQL;
$query = '{
artists {
edges {
node {
id
name
performances {
edges {
node {
venue
}
}
}
}
}
}
}';
$result = GraphQL::executeQuery(
schema: $schema,
source: $query,
variableValues: null,
operationName: null
);
$output = $result->toArray();
Run GraphQL mutations
use GraphQL\GraphQL;
$query = '
mutation ArtistUpdateName($id: Int!, $name: String!) {
artistUpdateName(id: $id, input: { name: $name }) {
id
name
}
}
';
$result = GraphQL::executeQuery(
schema: $schema,
source: $query,
variableValues: [
'id' => 1,
'name' => 'newName',
],
operationName: 'ArtistUpdateName'
);
$output = $result->toArray();
For every enabled field and association, filters are available for querying.
Example
{
artists (
filter: {
name: {
contains: "Dead"
}
}
) {
edges {
node {
id
name
performances (
filter: {
venue: {
eq: "The Fillmore"
}
}
) {
edges {
node {
venue
}
}
}
}
}
}
}
Each field has their own set of filters. Based on the field type, some or all of the following filters are available:
- eq - Equals.
- neq - Not equals.
- lt - Less than.
- lte - Less than or equal to.
- gt - Greater than.
- gte - Greater than or equal to.
- isnull - Is null. If value is true, the field must be null. If value is false, the field must not be null.
- between - Between. Identical to using gte & lte on the same field. Give values as
low, high
. - in - Exists within an array.
- notin - Does not exist within an array.
- startwith - A like query with a wildcard on the right side of the value.
- endswith - A like query with a wildcard on the left side of the value.
- contains - A like query.
You may exclude any filter from any entity, association, or globally.
The roots of this project go back to May 2018 with https://github.com/API-Skeletons/zf-doctrine-graphql; written for Zend Framework 2. It was migrated to the framework agnostic https://packagist.org/packages/api-skeletons/doctrine-graphql but the name of that repository was incorrect because it did not specify ORM only. So this repository was created and the others were abandoned.
See LICENSE.