arthem/graphql-mapper-bundle
Install the Bundle
composer require arthem/graphql-mapper-bundle
Enable the Bundle
Add to app/AppKernel.php:
new Arthem\Bundle\GraphQLBundle\ArthemGraphQLBundle(),
Define Your Schema
Create app/config/graphql_schema.yml with a basic schema:
types:
Query:
fields:
hello:
type: String
resolve: "function() { return 'World'; }"
Configure the Bundle
In app/config/config.yml:
arthem_graphql:
mapping:
files:
- %kernel.root_dir%/config/graphql_schema.yml
Set Up Routing
Add to app/config/routing.yml:
arthem_graphql:
resource: "@ArthemGraphQLBundle/Resources/config/routing.yml"
prefix: /graphql
Test the Endpoint
Send a POST request to /graphql with:
{
"query": "{ hello }"
}
Map a Doctrine entity to a GraphQL type:
# app/config/graphql_schema.yml
types:
User:
fields:
id:
type: Int
resolve: "function($obj) { return $obj->getId(); }"
name:
type: String
resolve: "function($obj) { return $obj->getName(); }"
Define Types Use YAML to map entities to GraphQL types:
types:
Product:
fields:
id: { type: Int, resolve: "function($obj) { return $obj->getId(); }" }
name: { type: String, resolve: "function($obj) { return $obj->getName(); }" }
price: { type: Float, resolve: "function($obj) { return $obj->getPrice(); }" }
Resolve with Services Inject services into resolvers:
types:
Order:
fields:
total:
type: Float
resolve: "@app.service.order_calculator.calculate"
Query and Mutations Define root-level operations:
types:
Query:
fields:
products:
type: "[Product]"
args:
limit: { type: Int }
resolve: "@app.repository.product.findAll"
Mutation:
fields:
createProduct:
type: Product
args:
name: { type: String }
price: { type: Float }
resolve: "@app.service.product.create"
Dependency Injection Use Symfony’s DI to pass services to resolvers:
types:
User:
fields:
posts:
type: "[Post]"
resolve: "@app.service.user.getPosts"
Authentication Secure endpoints via Symfony’s security system:
# app/config/security.yml
access_control:
- { path: ^/graphql, roles: ROLE_USER }
Validation Validate input args using Symfony’s Validator:
types:
Mutation:
fields:
updateUser:
type: User
args:
id: { type: Int }
name: { type: String, validate: "NotBlank" }
resolve: "@app.service.user.update"
Schema-First Development
Incremental Adoption
Testing
public function testHelloResolver()
{
$this->client->request('POST', '/graphql', [
'json' => ['query' => '{ hello }']
]);
$this->assertEquals('World', $this->client->getResponse()->getContent());
}
Outdated Dependencies
arthem/graphql-mapper (last updated in 2016). Ensure compatibility with your PHP/Doctrine versions.YAML Schema Limitations
No Built-in Playground
Caching Schema
php bin/console cache:clear).Error Handling
types:
Query:
fields:
riskyOperation:
type: String
resolve: |
try {
return $this->doRiskyStuff();
} catch (\Exception $e) {
return "Error: " . $e->getMessage();
}
Enable Debug Mode
Set app.debug: true in config.yml to see detailed errors.
Log Resolver Calls Add logging to resolvers:
types:
Query:
fields:
debug:
type: String
resolve: |
\Symfony\Component\Debug\Debug::dump($obj);
return "Logged!";
Validate Schema
Use the graphql-mapper CLI tool to validate your YAML schema:
vendor/bin/graphql-mapper validate app/config/graphql_schema.yml
Custom Directives Extend the schema with custom directives (if supported by the underlying mapper):
directives:
auth:
locations: [QUERY, MUTATION]
args:
role: { type: String }
Middleware Add middleware to the GraphQL pipeline (if the mapper supports it):
arthem_graphql:
middleware:
- "@app.middleware.graphql_logger"
Subscriptions The bundle may not support subscriptions out of the box. For real-time features:
Batch Loading
Use Doctrine’s Hydrator or ResultCache to optimize resolver performance:
types:
User:
fields:
posts:
type: "[Post]"
resolve: "@app.service.user.getPostsWithBatchLoading"
Lazy Loading Avoid N+1 queries by eager-loading associations in resolvers:
types:
User:
fields:
orders:
type: "[Order]"
resolve: "@app.service.user.getOrdersWithEagerLoading"
Caching Resolvers Cache resolver results for static data:
types:
Query:
fields:
config:
type: String
resolve: "@app.cache.graphql_config"
How can I help you explore Laravel packages today?