Installation
composer require avris/graphql-bundle
Add to config/bundles.php:
return [
Avris\GraphQLBundle\AvrisGraphQLBundle::class => ['all' => true],
];
Basic Configuration Define a GraphQL schema class with annotations:
use Avris\GraphQLBundle\Annotation\GraphQLType;
use Avris\GraphQLBundle\Annotation\GraphQLField;
#[GraphQLType(name: 'User')]
class UserType
{
#[GraphQLField]
public function name(): string { return 'John Doe'; }
#[GraphQLField]
public function email(): string { return 'john@example.com'; }
}
First Query
Register the type in config/packages/avris_graphql.yaml:
types:
- Avris\GraphQLBundle\Tests\Type\UserType
Run the schema generator:
php bin/console avris:graphql:generate
Test via GraphQL endpoint (/graphql by default):
query {
user {
name
email
}
}
@GraphQLType and @GraphQLField for type/class definitions.avris:graphql:generate after any schema changes.avris:graphql:debug to inspect generated schema.Type Definition
#[GraphQLType(name: 'Product')]
class ProductType
{
#[GraphQLField]
public function id(): int { return $this->id; }
#[GraphQLField(type: 'String!')] // Non-nullable string
public function name(): string { return $this->name; }
}
Query/Resolver Integration Bind a resolver to a query:
#[GraphQLType(name: 'Query')]
class QueryType
{
#[GraphQLField(type: 'User')]
public function user(UserRepository $repo): UserType {
return new UserType($repo->find(1));
}
}
Input Types
#[GraphQLType(name: 'CreateUserInput')]
class CreateUserInputType
{
#[GraphQLField(type: 'String!')]
public string $name;
#[GraphQLField(type: 'String!')]
public string $email;
}
Mutations
#[GraphQLType(name: 'Mutation')]
class MutationType
{
#[GraphQLField(type: 'User')]
public function createUser(
CreateUserInputType $input,
UserService $service
): UserType {
return $service->create($input);
}
}
UserRepository).Avris\GraphQLBundle\Scalar\Scalar for custom types (e.g., DateTime).@GraphQLDirective for custom logic (e.g., @auth).#[Assert\NotBlank]) for input validation.Interfaces and Unions
#[GraphQLType(name: 'Node', isInterface: true)]
interface NodeType {}
#[GraphQLType(name: 'User', interfaces: ['Node'])]
class UserType implements NodeType {}
Fragment Spreads
#[GraphQLType(name: 'User', fragments: ['UserFragment'])]
class UserType {}
Batch Loading
Use Avris\GraphQLBundle\DataLoader\DataLoader for N+1 queries:
$loader = new DataLoader($this->repository->batchFind(...));
Schema Regeneration
avris:graphql:generate after adding new types.php bin/console avris:graphql:watch in development.Circular Dependencies
User → Post → User).Type Mismatches
null for non-nullable fields (String!).#[GraphQLField(type: 'String')] for nullable fields or ensure resolver logic handles null.Annotation Caching
php bin/console cache:clear or use avris:graphql:clear-cache.Schema Inspection:
php bin/console avris:graphql:debug
Outputs the full generated schema in JSON.
Query Validation:
Use GraphQL Playground (enabled by default at /graphql) to test queries interactively.
Error Logging:
Enable debug mode in config/packages/avris_graphql.yaml:
debug: true
Endpoint Customization
Override the default /graphql endpoint in config:
endpoint: '/api/graphql'
Middleware
Add custom middleware (e.g., auth) in config/packages/avris_graphql.yaml:
middleware:
- Avris\GraphQLBundle\Middleware\AuthMiddleware
CORS
Configure CORS in config/packages/avris_graphql.yaml:
cors:
allow_origin: ['*']
allow_methods: ['GET', 'POST']
Custom Directives Create a directive class:
use Avris\GraphQLBundle\Annotation\GraphQLDirective;
#[GraphQLDirective(name: 'auth')]
class AuthDirective {}
Scalar Extensions Register a custom scalar:
scalars:
DateTime: Avris\GraphQLBundle\Scalar\DateTimeScalar
Plugin System
Implement Avris\GraphQLBundle\Plugin\PluginInterface for custom logic (e.g., logging, metrics).
Validation Rules Extend input validation with custom rules:
use Avris\GraphQLBundle\Validator\Constraint;
#[Constraint('Custom\Rule')]
#[GraphQLField]
public string $customField;
How can I help you explore Laravel packages today?