api-skeletons/doctrine-orm-graphql

GraphQL Type Driver for Doctrine ORM

12.3.4 2024-12-23 08:54 UTC

README

GraphQL Type Driver for Doctrine ORM

Build Status Code Coverage Scrutinizer Code Quality PHPStan psalm PHP Version License

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.

Many other GraphQL libraries for Doctrine ORM are available.
Some of these such as overblog/graphql-bundle and API Platform are integrations into frameworks. But all of these libraries use the same underlying library, webonyx/graphql-php and that library has its own way of doing things. This library is a driver for that library and together they are framework agnostic.

Installation

Via composer:

composer require api-skeletons/doctrine-orm-graphql

Documentation

Full documentation is available at https://doctrine-orm-graphql.apiskeletons.dev or in the docs directory.

Versions

More information in the documentation.

Examples

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.

Features

Quick Start

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();

Filters

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.

History

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.

License

See LICENSE.