Download the PHP package ecodev/graphql-doctrine without Composer

On this page you can find all versions of the php package ecodev/graphql-doctrine. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.

FAQ

After the download, you have to make one include require_once('vendor/autoload.php');. After that you have to import the classes with use statements.

Example:
If you use only one package a project is not needed. But if you use more then one package, without a project it is not possible to import the classes with use statements.

In general, it is recommended to use always a project to download your libraries. In an application normally there is more than one library needed.
Some PHP packages are not free to download and because of that hosted in private repositories. In this case some credentials are needed to access such packages. Please use the auth.json textarea to insert credentials, if a package is coming from a private repository. You can look here for more information.

  • Some hosting areas are not accessible by a terminal or SSH. Then it is not possible to use Composer.
  • To use Composer is sometimes complicated. Especially for beginners.
  • Composer needs much resources. Sometimes they are not available on a simple webspace.
  • If you are using private repositories you don't need to share your credentials. You can set up everything on our site and then you provide a simple download link to your team member.
  • Simplify your Composer build process. Use our own command line tool to download the vendor folder as binary. This makes your build process faster and you don't need to expose your credentials for private repositories.
Please rate this library. Is it a good library?

Informations about the package graphql-doctrine

GraphQL Doctrine

Build Status Code Quality Code Coverage Total Downloads Latest Stable Version License Join the chat at https://gitter.im/Ecodev/graphql-doctrine

A library to declare GraphQL types from Doctrine entities, PHP type hinting, and attributes, and to be used with webonyx/graphql-php.

It reads most information from type hints, complete some things from existing Doctrine attributes and allow further customizations with specialized attributes. It will then create ObjectType and InputObjectType instances with fields for all getter and setter respectively found on Doctrine entities.

It will not build the entire schema. It is up to the user to use automated types, and other custom types, to define root queries.

Quick start

Install the library via composer:

And start using it:

Usage

The public API is limited to the public methods on TypesInterface, Types's constructor, and the attributes.

Here is a quick overview of TypesInterface:

Information priority

To avoid code duplication as much as possible, information are gathered from several places, where available. And each of those might be overridden. The order of priority, from the least to most important is:

  1. Type hinting
  2. Doc blocks
  3. Attributes

That means it is always possible to override everything with attributes. But existing type hints and dock blocks should cover the majority of cases.

Exclude sensitive things

All getters, and setters, are included by default in the type. And all properties are included in the filters. But it can be specified otherwise for each method and property.

To exclude a sensitive field from ever being exposed through the API, use #[API\Exclude]:

And to exclude a property from being exposed as a filter:

Override output types

Even if a getter returns a PHP scalar type, such as string, it might be preferable to override the type with a custom GraphQL type. This is typically useful for enum or other validation purposes, such as email address. This is done by specifying the GraphQL type FQCN via #[API\Field] attribute:

Type syntax

In most cases, the type must use the ::class notation to specify the PHP class that is either implementing the GraphQL type or the entity itself (see limitations). Use string literals only if you must define it as nullable and/or as an array. Never use the short name of an entity (it is only possible for user-defined custom types).

Supported syntaxes (PHP style or GraphQL style) are:

This attribute can be used to override other things, such as name, description and args.

Override arguments

Similarly to #[API\Field], #[API\Argument] allows to override the type of argument if the PHP type hint is not enough:

Once again, it also allows to override other things such as name, description and defaultValue.

Override input types

#[API\Input] is the opposite of #[API\Field] and can be used to override things for input types (setters), typically for validations purpose. This would look like:

This attribute also supports description, and defaultValue.

Override filter types

#[API\FilterGroupCondition] is the equivalent for filters that are generated from properties. So usage would be like:

An important thing to note is that the value of the type specified will be directly used in DQL. That means that if the value is not a PHP scalar, then it must be convertible to string via __toString(), or you have to do the conversion yourself before passing the filter values to Types::createFilteredQueryBuilder().

Custom types

By default, all PHP scalar types and Doctrine collection are automatically detected and mapped to a GraphQL type. However, if some getter return custom types, such as DateTimeImmutable, or a custom class, then it will have to be configured beforehand.

The configuration is done with a PSR-11 container implementation configured according to your needs. In the following example, we use laminas/laminas-servicemanager, because it offers useful concepts such as: invokables, aliases, factories and abstract factories. But any other PSR-11 container implementation could be used instead.

The keys should be the whatever you use to refer to the type in your model. Typically, that would be either the FQCN of a PHP class "native" type such as DateTimeImmutable, or the FQCN of a PHP class implementing the GraphQL type, or directly the GraphQL type name:

That way it is not necessary to annotate every single getter returning one of the configured type. It will be mapped automatically.

Entities as input arguments

If a getter takes an entity as parameter, then a specialized InputType will be created automatically to accept an ID. The entity will then be automatically fetched from the database and forwarded to the getter. So this will work out of the box:

You may also get an input type for an entity by using Types::getId() to write things like:

Partial inputs

In addition to normal input types, it is possible to get a partial input type via getPartialInput(). This is especially useful for mutations that update existing entities, when we do not want to have to re-submit all fields. By using a partial input, the API client is able to submit only the fields that need to be updated and nothing more.

This potentially reduces network traffic, because the client does not need to fetch all fields just to be able re-submit them when he wants to modify only one field.

And it also enables to easily design mass editing mutations where the client would submit only a few fields to be updated for many entities at once. This could look like:

Default values

Default values are automatically detected from arguments for getters, as seen in getPosts() example above.

For setters, the default value will be looked up on the mapped property, if there is one matching the setter name. But if the setter itself has an argument with a default value, it will take precedence.

So the following will make an input type with an optional field name with a default value john, an optional field foo with a default value defaultFoo and a mandatory field bar without any default value:

Filtering and sorting

It is possible to expose generic filtering for entity fields and their types to let users easily create and apply generic filters. This expose basic SQL-like syntax that should cover most simple cases.

Filters are structured in an ordered list of groups. Each group contains an unordered set of joins and conditions on fields. For simple cases a single group of a few conditions would probably be enough. But the ordered list of group allow more advanced filtering with OR logic between a set of conditions.

In the case of the Post class, it would generate that GraphQL schema for filtering, and for sorting it would be that simpler schema.

For concrete examples of possibilities and variables syntax, refer to the test cases.

For security and complexity reasons, it is not meant to solve advanced use cases. For those it is possible to write custom filters and sorting.

Custom filters

A custom filer must extend AbstractOperator. This will allow to define custom arguments for the API, and then a method to build the DQL condition corresponding to the argument.

This would also allow to filter on joined relations by carefully adding joins when necessary.

Then a custom filter might be used like so:

Custom sorting

A custom sorting option must implement SortingInterface. The constructor has no arguments and the __invoke() must define how to apply the sorting.

Similarly to custom filters, it may be possible to carefully add joins if necessary.

Then a custom sorting might be used like so:

Limitations

Namespaces

The use statement is not supported. So types in attributes or doc blocks must be the FQCN, or the name of a user-defined custom types (but never the short name of an entity).

Composite identifiers

Entities with composite identifiers are not supported for automatic creation of input types. Possible workarounds are to change input argument to be something else than an entity, write custom input types and use them via attributes, or adapt the database schema.

Logical operators in filtering

Logical operators support only two levels, and second level cannot mix logic operators. In SQL that would mean only one level of parentheses. So you can generate SQL that would look like:

But you cannot generate SQL that would like that:

Those cases would probably end up being too complex to handle on the client-side. And we recommend instead to implement them as a custom filter on the server side, in order to hide complexity from the client and benefit from Doctrine's QueryBuilder full flexibility.

Sorting on join

Out of the box, it is not possible to sort by a field from a joined relation. This should be done via a custom sorting to ensure that joins are done properly.

Prior work

Doctrine GraphQL Mapper has been an inspiration to write this package. While the goals are similar, the way it works is different. In Doctrine GraphQL Mapper, attributes are spread between properties and methods (and classes for filtering), but we work only on methods. Setup seems slightly more complex, but might be more flexible. We built on conventions and widespread use of PHP type hinting to have an easier out-of-the-box experience.


All versions of graphql-doctrine with dependencies

PHP Build Version
Package Version
Requires php Version ^8.2
doctrine/orm Version ^2.15
psr/container Version ^1.1 || ^2.0
webonyx/graphql-php Version ^15.7
Composer command for our command line client (download client) This client runs in each environment. You don't need a specific PHP version etc. The first 20 API calls are free. Standard composer command

The package ecodev/graphql-doctrine contains the following files

Loading the files please wait ....