api-skeletons/doctrine-orm-graphql

GraphQL Type Driver for Doctrine ORM

12.2.4 2024-11-18 18:44 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.

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.