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
annotation. 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.
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 annotations / attributes
GraphQLite relies a lot on annotations (we call them attributes since PHP 8).
It supports both the old "Doctrine annotations" style (@Query
) and the new PHP 8 attributes (#[Query]
).
Read the Doctrine annotations VS attributes documentation if you are not familiar with this concept.
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)
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
annotation is used to inform GraphQLite that the Product
class is a GraphQL type.
The @Field
annotation is used to define the GraphQL fields. This annotation 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 annotations are adding some serialization logic that is out of scope of the domain. These are just annotations and for most project, this is the fastest and easiest route.
If you feel that GraphQL annotations 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.