Skip to main content
Version: 8.0.0

Queries

In GraphQLite, GraphQL queries are created by writing methods in controller classes.

Those classes must be in the controllers namespaces which has been defined when you configured GraphQLite. For instance, in Symfony, the controllers namespace is App\Controller by default.

Simple query

In a controller class, each query method must be annotated with the #[Query] attribute. For instance:

namespace App\Controller;

use TheCodingMachine\GraphQLite\Annotations\Query;

class MyController
{
#[Query]
public function hello(string $name): string
{
return 'Hello ' . $name;
}
}

This query is equivalent to the following GraphQL type language:

Type Query {
hello(name: String!): String!
}

As you can see, GraphQLite will automatically do the mapping between PHP types and GraphQL types.

Heads up! If you are not using a framework with an autowiring container (like Symfony or Laravel), please be aware that the MyController class must exist in the container of your application. Furthermore, the identifier of the controller in the container MUST be the fully qualified class name of controller.

About attributes

GraphQLite relies a lot on attributes.

It supports the new PHP 8 attributes (#[Query]), the "Doctrine annotations" style (#[Query]) was dropped.

Testing the query

The default GraphQL endpoint is /graphql.

The easiest way to test a GraphQL endpoint is to use GraphiQL or Altair clients (they are available as Chrome or Firefox plugins)

If you are using the Symfony bundle, GraphiQL is also directly embedded.
Simply head to http://[path-to-my-app]/graphiql

Here a query using our simple Hello World example:

Query with a type

So far, we simply declared a query. But we did not yet declare a type.

Let's assume you want to return a product:

namespace App\Controller;

use TheCodingMachine\GraphQLite\Annotations\Query;

class ProductController
{
#[Query]
public function product(string $id): Product
{
// Some code that looks for a product and returns it.
}
}

As the Product class is not a scalar type, you must tell GraphQLite how to handle it:

namespace App\Entities;

use TheCodingMachine\GraphQLite\Annotations\Field;
use TheCodingMachine\GraphQLite\Annotations\Type;

#[Type]
class Product
{
// ...

#[Field]
public function getName(): string
{
return $this->name;
}

#[Field]
public function getPrice(): ?float
{
return $this->price;
}
}

The #[Type] attribute is used to inform GraphQLite that the Product class is a GraphQL type.

The #[Field] attribute is used to define the GraphQL fields. This attribute must be put on a public method.

The Product class must be in one of the types namespaces. As for controller classes, you configured this namespace when you installed GraphQLite. By default, in Symfony, the allowed types namespaces are App\Entity and App\Types.

This query is equivalent to the following GraphQL type language:

Type Product {
name: String!
price: Float
}

If you are used to Domain driven design, you probably realize that the Product class is part of your domain.

GraphQL attributes are adding some serialization logic that is out of scope of the domain. These are just attributes and for most project, this is the fastest and easiest route.

If you feel that GraphQL attributes do not belong to the domain, or if you cannot modify the class directly (maybe because it is part of a third party library), there is another way to create types without annotating the domain class. We will explore that in the next chapter.