api-skeletons/doctrine-orm-graphql

GraphQL Type Driver for Doctrine ORM

11.0.2 2024-04-24 19:45 UTC

README

68747470733a2f2f706c616365686f6c642e636f2f31307831302f3333376162372f3333376162372e706e67 banner.png

GraphQL Type Driver for Doctrine ORM

Build Status Code Coverage Scrutinizer Code Quality PHP Version Total Downloads 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.

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' => [
                'type' => $driver->connection(Artist::class),
                'args' => [
                    'filter' => $driver->filter(Artist::class),
                    'pagination' => $driver->pagination(),
                ],
                'resolve' => $driver->resolve(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.

Event Manager Versions

The event manager used in this library is from league/event. There are two supported versions of the event manager library by The PHP League and their API is very different. In this library, version 3 of league/event has always been used. Version 3 is a PSR-14 compliant event manager.

However, The PHP League does not use the latest version of their own event manager in their league/oauth2-server. Because of this old version requirement, it was not possible to install the league/oauth2-server library and this library in the same project. Version 11 of api-skeletons/doctrine-orm-graphql has regressive support for league/event by supporting version 2 of that library instead of version 3. Version 2 is not PSR-14 compliant.

If you need to install league/oauth2-server and api-skeletons/doctrine-orm-graphql in the same project, you must use version 11 of this library.

If you do not need to install league/oauth2-server and api-skeletons/doctrine-orm-graphql in the same project, you should use version 10 of this library.

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.