### Install Overblog GraphQL Bundle
Source: https://github.com/overblog/graphqlbundle/blob/master/docs/definitions/quick-start.md
Use Composer to install the bundle. Refer to the documentation for more details on installation.
```bash
composer require overblog/graphql-bundle
```
--------------------------------
### Install OverblogGraphQLBundle
Source: https://context7.com/overblog/graphqlbundle/llms.txt
Install the bundle using Composer. The GraphiQL browser UI is optional and requires a separate development dependency.
```bash
composer require overblog/graphql-bundle
# Optional: GraphiQL browser UI
composer require --dev overblog/graphiql-bundle
```
--------------------------------
### Generated Configuration Example
Source: https://github.com/overblog/graphqlbundle/blob/master/docs/definitions/builders/field.md
The resulting GraphQL configuration generated from the field builder example.
```yaml
Mutation:
type: object
config:
fields:
foo:
type: 'FooPayload!'
resolve: '@=mutation("Mutation.foo", [args["input"]])'
args:
input: {type: 'FooInput!'}
FooInput:
type: input-object
config:
fields:
bar: {type: 'String!'}
FooPayload:
type: union
config:
types: ['FooSuccessPayload', 'FooFailurePayload']
resolveType: '@=query("PayloadTypeResolver", value, "FooSuccessPayload", "FooFailurePayload")'
FooSuccessPayload:
type: object
config:
fields:
fooString: {type: 'String!'}
FooFailurePayload:
type: object
config:
fields:
_error: {type: 'String'}
bar: {type: 'String'}
```
--------------------------------
### Relay Paginator Forward Pagination Example
Source: https://context7.com/overblog/graphqlbundle/llms.txt
Demonstrates using the `Paginator` class for forward pagination. It takes a callback to fetch data slices and uses `forward()` with `first` and `after` arguments to get a specific page.
```php
forward(new Argument([
'first' => 2,
'after' => base64_encode('arrayconnection:1'), // after "B"
]));
// $result->edges[0]->node === 'C'
// $result->edges[1]->node === 'D'
// $result->pageInfo->hasNextPage === true
```
--------------------------------
### Field Builder Configuration Example
Source: https://github.com/overblog/graphqlbundle/blob/master/docs/definitions/builders/field.md
Example of how to configure a field using a builder, specifying the builder class and its configuration.
```yaml
Mutation:
type: object
config:
fields:
foo:
builder: 'Mutation'
builderConfig:
name: 'Foo'
resolver: 'Mutation.foo'
inputFields:
bar: {type: 'String!'}
payloadFields:
fooString: {type: 'String!'}
```
--------------------------------
### Mutation Resolver Example (createShip)
Source: https://context7.com/overblog/graphqlbundle/llms.txt
Example of a PHP resolver class for handling the 'createShip' mutation. It implements MutationInterface and AliasedInterface.
```APIDOC
## Mutation Resolver: ShipMutation
### Class
`App\GraphQL\Mutation\ShipMutation`
### Implements
`MutationInterface`, `AliasedInterface`
### Constructor
- **factionRepository**: `FactionRepository`
### Method
- **createShip**(shipName: String!, factionId: Int!): array
- Description: Creates a new ship and associates it with a faction.
- Alias: `create_ship`
- Returns: An array containing the created `ship` and the `faction`.
```
--------------------------------
### Query Type Example
Source: https://context7.com/overblog/graphqlbundle/llms.txt
Example configuration for a Query type, demonstrating the use of built-in functions for field resolution and access control.
```APIDOC
```yaml
# config/graphql/types/Query.types.yaml
Query:
type: object
config:
fields:
me:
type: "User!"
# Requires authentication; uses current user
resolve: "@=getUser()"
access: "@=isAuthenticated()"
settings:
type: "Settings"
# Access a Symfony service
resolve: "@=service('App\\Service\\SettingsManager').getForUser(getUser())"
debugMode:
type: "Boolean!"
# Read a container parameter
resolve: "@=parameter('kernel.debug')"
hero:
type: "Character"
args:
episode: { type: "Episode" }
# Call resolver alias with argument
resolve: "@=query('character_hero', args['episode'])"
```
```
--------------------------------
### cURL Example for File Upload
Source: https://context7.com/overblog/graphqlbundle/llms.txt
Provides a `curl` command example for uploading a file to a GraphQL endpoint, demonstrating how to structure the request with operations and file mapping.
```bash
# curl upload example
curl 'http://localhost:8000/' \
-F operations='{"query":"mutation($file:Upload!){singleUpload(file:$file)}","variables":{"file":null}}' \
-F map='{"0":["variables.file"]}' \
-F 0=@/path/to/file.png
```
--------------------------------
### Install GraphiQL Interface Bundle
Source: https://github.com/overblog/graphqlbundle/blob/master/docs/index.md
If you wish to use the GraphiQL interface for testing your GraphQL API, install this development bundle using Composer.
```bash
composer require --dev overblog/graphiql-bundle
```
--------------------------------
### Equivalent Configuration After Builder Application
Source: https://github.com/overblog/graphqlbundle/blob/master/docs/definitions/builders/fields.md
This YAML shows the expanded configuration equivalent to the previous example after the `Timestamped` builder has been applied.
```yaml
User:
type: object
config:
fields:
createdAt:
description: The creation date of the object
type: Int!
resolve: "@=value.dateCreated"
updatedAt:
description: The update date of the object
type: Int!
resolve: "@=value.updatedAt"
```
--------------------------------
### Permission Check Example
Source: https://github.com/overblog/graphqlbundle/blob/master/docs/definitions/type-inheritance.md
This example shows how to define a permission check using a query function, specifying the attribute and subject for the permission.
```twig
resolve: '@=query("Permission.nodeAttribute", "edit", value)'
```
--------------------------------
### Example GraphQL Query for Relay Connection
Source: https://context7.com/overblog/graphqlbundle/llms.txt
An example GraphQL query demonstrating how to fetch paginated `friends` data using Relay connection arguments like `first` and `after`, and accessing `edges`, `node`, `cursor`, `pageInfo`, and `totalCount`.
```graphql
# Example query
{
user {
friends(first: 2, after: "YXJyYXljb25uZWN0aW9uOjA=") {
edges {
cursor
node { name }
friendshipTime
}
pageInfo { hasNextPage hasPreviousPage }
totalCount
}
}
}
```
--------------------------------
### Define Human and Droid Classes
Source: https://github.com/overblog/graphqlbundle/blob/master/docs/definitions/type-system/interface.md
Example classes for Human and Droid, which will be used to demonstrate interface implementation.
```php
class Human
{
public $id;
public $name;
public $friends;
public $appearsIn;
public $starships;
public $totalCredits;
// ...
}
class Droid
{
public $id;
public $name;
public $friends;
public $appearsIn;
public $primaryFunction;
// ...
}
```
--------------------------------
### Query Resolver Example (findHuman)
Source: https://context7.com/overblog/graphqlbundle/llms.txt
Example of a PHP resolver class for handling 'findHuman' query. It implements QueryInterface and AliasedInterface for mapping.
```APIDOC
## Query Resolver: CharacterResolver
### Class
`App\GraphQL\Resolver\CharacterResolver`
### Implements
`QueryInterface`, `AliasedInterface`
### Constructor
- **repo**: `CharacterRepository`
### Methods
- **findHuman**(id: String!): ?array
- Description: Finds a human by ID.
- Alias: `character_human`
- **resolveCharacterType**(value: mixed, typeResolver: TypeResolver)
- Description: Resolves the GraphQL type for a given value.
- Alias: `character_type`
```
--------------------------------
### Field Builder Implementation Example
Source: https://github.com/overblog/graphqlbundle/blob/master/docs/definitions/builders/field.md
PHP implementation of a field builder that defines a mutation field with input and payload types.
```php
['type' => 'String'],
];
foreach (
eal_keys($inputFields) as $fieldName) {
$failurePayloadFields[$fieldName] = ['type' => 'String'];
}
$payloadTypeName = $name.'Payload';
$payloadSuccessTypeName = $name.'SuccessPayload';
$payloadFailureTypeName = $name.'FailurePayload';
$inputTypeName = $name.'Input';
$field = [
'type' => $payloadTypeName.'!',
'resolve' => ".sprintf('@=mutation(\"%s\", args[\"input\"])", $resolver),
'args' => [
'input' => $inputTypeName.'!',
],
];
$types = [
$inputTypeName => [
'type' => 'input-object',
'config' => [
'fields' => $inputFields,
],
],
$payloadTypeName => [
'type' => 'union',
'config' => [
'types' => [$payloadSuccessTypeName, $payloadFailureTypeName],
'resolveType' => ".sprintf('@=query(\"PayloadTypeResolver\", value, \"%s\", \"%s\")', $payloadSuccessTypeName, $payloadFailureTypeName),
],
],
$payloadSuccessTypeName => [
'type' => 'object',
'config' => [
'fields' => $successPayloadFields,
],
],
$payloadFailureTypeName => [
'type' => 'object',
'config' => [
'fields' => $failurePayloadFields,
],
],
];
return ['field' => $field, 'types' => $types];
}
}
```
--------------------------------
### Create Promise with PromiseAdapter Service
Source: https://github.com/overblog/graphqlbundle/blob/master/docs/data-fetching/promise.md
Use the injected `overblog_graphql.promise_adapter` service to create promises within your resolvers. This example demonstrates creating a promise that resolves with user data.
```php
promiseAdapter = $promiseAdapter;
}
public function resolveQuery()
{
return $this->promiseAdapter->create(function (callable $resolve) {
return $resolve(['name' => 'Luke']);
});
}
}
```
--------------------------------
### Custom Relay Connection and Edge Classes
Source: https://context7.com/overblog/graphqlbundle/llms.txt
Example of using custom connection and edge classes with `ConnectionBuilder`. This allows for more control over the structure and data of the connection and its edges.
```php
// Custom connection/edge classes
use Overblog\GraphQLBundle\Relay\Connection\ConnectionBuilder;
use Overblog\GraphQLBundle\Relay\Connection\Cursor\Base64CursorEncoder;
$builder = new ConnectionBuilder(
new Base64CursorEncoder(),
function (iterable $edges, $pageInfo): FriendsConnection {
$conn = new FriendsConnection($edges, $pageInfo);
$conn->setTotalCount(count($edges));
return $conn;
},
function (string $cursor, UserFriend $friend, int $index): FriendEdge {
$edge = new FriendEdge($cursor, $friend->getUser());
$edge->setFriendshipTime($friend->getCreatedAt());
return $edge;
}
);
$paginator = new Paginator(fn($offset, $limit) => $repo->getSlice($offset), Paginator::MODE_RELAY, $builder);
```
--------------------------------
### PHP Mutation Resolver Implementation
Source: https://github.com/overblog/graphqlbundle/blob/master/docs/definitions/mutation.md
Example PHP class implementing the mutation logic for 'create_ship'. It demonstrates how to access input arguments and return a payload conforming to 'IntroduceShipPayload'.
```APIDOC
## PHP Mutation Resolver
### Description
Implements the `createShip` method to handle the `create_ship` mutation logic.
### Class
```php
factionRepository = $factionRepository;
}
public function createShip(string $shipName, int $factionId): array
{
// `$shipName` has the value of `args['input']['shipName']`
// `$factionId` has the value of `args['input']['factionId']`
// Do something with `$shipName` and `$factionId` ...
$ship = new Ship($shipName);
$faction = $this->factionRepository->find($factionId);
$faction->addShip($ship);
// ...
// Then returns our payload, it should fits `IntroduceShipPayload` type
return [
'ship' => $ship,
'faction' => $faction,
];
}
/**
* {@inheritdoc}
*/
public static function getAliases(): array
{
return [
// `create_ship` is the name of the mutation that you SHOULD use inside of your types definition
// `createShip` is the method that will be executed when you call `@=mutation('create_ship')`
'createShip' => 'create_ship'
];
}
}
```
```
--------------------------------
### Configure Default Field Resolver Globally
Source: https://github.com/overblog/graphqlbundle/blob/master/UPGRADE.md
Example of configuring a custom default field resolver service globally within the bundle configuration.
```yaml
overblog_graphql:
definitions:
default_field_resolver: 'App\GraphQL\CustomResolver'
```
--------------------------------
### Initialize rootValue with Current User
Source: https://github.com/overblog/graphqlbundle/blob/master/docs/events/index.md
Use the `graphql.pre_executor` event to set the `rootValue` argument before execution, for example, by providing the authenticated user.
```yaml
App\EventListener\RootValueInitialization:
tags:
- { name: kernel.event_listener, event: graphql.pre_executor, method: onPreExecutor }
```
```php
token = $token;
}
public function onPreExecutor(ExecutorArgumentsEvent $event)
{
$event->setRootValue($this->token->getUser());
}
}
```
--------------------------------
### Configure Default Field Resolver Per Type
Source: https://github.com/overblog/graphqlbundle/blob/master/UPGRADE.md
Example of configuring a specific field resolver for a particular type within the bundle configuration.
```yaml
MyType:
type: object
config:
resolveField: 'App\GraphQL\MyTypeResolver::defaultFieldResolver'
fields:
name: {type: String}
email: {type: String}
```
--------------------------------
### Example: GraphQL Type with Annotations
Source: https://github.com/overblog/graphqlbundle/blob/master/docs/attributes/index.md
Define a GraphQL type and field using annotations. The `/** @GQL ype */` annotation marks the class, and `/** @GQLield */` defines a field.
```php
use Overblog\GraphQLBundle\Annotation as GQL;
/**
* @GQL\Type
*/
class MyType {
/**
* @GQL\Field(type="Int")
*/
protected $myField;
}
```
--------------------------------
### Equivalent Schema Definition Without Args Builder
Source: https://github.com/overblog/graphqlbundle/blob/master/docs/definitions/builders/args.md
This example shows the expanded schema definition that the 'Pager' args builder generates, illustrating the equivalent arguments for 'limit' and 'offset'.
```yaml
foo:
type: "object"
config:
fields:
categories:
type: "[String!]!"
args:
limit:
type: "Int!"
defaultValue: 20
offset:
type: "Int!"
defaultValue: 0
categories2:
type: "[String!]!"
args:
limit:
type: "Int!"
defaultValue: 50
offset:
type: "Int!"
defaultValue: 0
```
--------------------------------
### GraphQL Response with Debug Information
Source: https://github.com/overblog/graphqlbundle/blob/master/docs/definitions/debug/index.md
This is an example of a GraphQL response when debug information is enabled, including execution time and memory usage.
```json
{
"data": [{"isEnabled": true}],
"extensions": {
"debug": {
"executionTime": "40 ms",
"memoryUsage": "1.00 MiB"
}
}
}
```
--------------------------------
### Custom isTypeOf Logic with Expression Language
Source: https://github.com/overblog/graphqlbundle/blob/master/docs/definitions/type-system/interface.md
Examples of using custom logic within the `isTypeOf` option, including calling static methods or service methods.
```yaml
Human:
type: object
config:
# Call a static method and pass the 'value' param to check its type
isTypeOf: '@=call("App\\GraphQL\\TypeResolver::isHuman", [value])'
# ... or even use a service
isTypeOf: '@=service("my_service").isTypeOfHuman(value)'
```
--------------------------------
### Timestamp Fields Builder Class Implementation
Source: https://github.com/overblog/graphqlbundle/blob/master/docs/definitions/builders/fields.md
Implement the `MappingInterface` to create a custom fields builder. This example defines `createdAt` and `updatedAt` fields, allowing configuration for property names.
```php
[
'description' => 'The creation date of the object',
'type' => 'Int!',
'resolve' => "@=value.$propertyCreatedAt",
],
'updatedAt' => [
'description' => 'The update date of the object',
'type' => 'Int!',
'resolve' => "@=value.$propertyUpdatedAt",
],
];
}
}
```
--------------------------------
### Set Root Value Before Execution
Source: https://context7.com/overblog/graphqlbundle/llms.txt
Listen to the `graphql.pre_executor` event to set the root value before GraphQL execution. This example sets the authenticated user as the root value.
```php
setRootValue($this->token->getUser());
}
}
```
```yaml
App\EventListener\RootValueInitialization:
tags:
- { name: kernel.event_listener, event: graphql.pre_executor, method: onPreExecutor }
```
--------------------------------
### Explicitly Defining Input Argument with Expression Language
Source: https://github.com/overblog/graphqlbundle/blob/master/docs/attributes/arguments-transformer.md
Manually define a mutation field and its arguments using annotations. This example demonstrates how to use the `call` expression function to invoke a service method, specifying the input argument type and using `arg` to pass the raw argument data.
```php
namespace App\GraphQL\Type;
use Overblog\GraphQLBundle\Annotation as GQL;
class RootMutation {
#[GQL\Field(type: "User", resolve: "@=call(service('UserRepository').createUser, arguments({input: 'UserRegisterInput'}, arg))")]
#[GQL\Arg(name: "input", type: "UserRegisterInput")]
public $createUser;
}
```
--------------------------------
### Creating a Custom Expression Function (json_decode)
Source: https://github.com/overblog/graphqlbundle/blob/master/docs/definitions/expression-language.md
Provides an example of creating a custom expression function equivalent to PHP's `json_decode`. This involves extending `ExpressionFunction` and registering the service with the `overblog_graphql.expression_function` tag.
```php
forward(
new Argument(
[
'first' => 1,
'after' => base64_encode('arrayconnection:2')
]
)
);
var_dump($result->edges);
```
--------------------------------
### Linking Validation Constraints to a Class (Doctrine Entity Example)
Source: https://github.com/overblog/graphqlbundle/blob/master/docs/validation/index.md
Demonstrates linking validation constraints to a Doctrine entity class. Note that validation context is not inherited, and validation methods will be called on ValidationNode objects.
```php
namespace App\Entity;
/**
* @Assert\Callback("validate")
*/
class User
{
public static function validate()
{
// ...
}
}
```
--------------------------------
### Defining GraphQL Type and Input with Fields
Source: https://github.com/overblog/graphqlbundle/blob/master/docs/attributes/attributes-reference.md
Demonstrates how to define a class as both a GraphQL Type and Input, with fields supporting different configurations. Fields on input types may be ignored if they are incompatible.
```php
connectionFromArray([]);
```
--------------------------------
### File Upload Scalar Type
Source: https://context7.com/overblog/graphqlbundle/llms.txt
Details the setup and usage of the `Upload` scalar type for handling file uploads in GraphQL mutations.
```APIDOC
## File Uploads
### Description
The Overblog GraphQL bundle provides a scalar type `Upload` compatible with `apollo-upload-client`. Uploaded files are accessible as `Symfony\Component\HttpFoundation\File\UploadedFile` instances within your resolvers.
### Configuration
1. **Register the scalar type:**
```yaml
Upload:
type: custom-scalar
config:
scalarType: '@=newObject("Overblog\\GraphQLBundle\\Upload\\Type\\GraphQLUploadType")'
```
2. **Use the `Upload` scalar in mutations:**
```yaml
Mutation:
type: object
config:
fields:
singleUpload:
type: "String!"
resolve: "@=args['file'].getClientOriginalName()"
args:
file: { type: "Upload!" }
multipleUpload:
type: "[String!]!"
resolve: "@=query('upload_handler', args['files'])"
args:
files: { type: "[Upload!]!" }
```
### cURL Example for Single Upload
```bash
curl 'http://localhost:8000/' \
-F operations='{"query":"mutation($file:Upload!){singleUpload(file:$file)}","variables":{"file":null}}' \
-F map='{"0":["variables.file"]}' \
-F 0=@/path/to/file.png
```
```
--------------------------------
### Configure Custom Promise Adapter
Source: https://github.com/overblog/graphqlbundle/blob/master/docs/data-fetching/promise.md
Configure the bundle to use a custom promise adapter service. Ensure the service implements the required PromiseAdapterInterface.
```yaml
overblog_graphql:
services:
promise_adapter: "my.promise_adapter"
```
--------------------------------
### Define Schema with YAML Configuration
Source: https://context7.com/overblog/graphqlbundle/llms.txt
Configure the main schema, specifying the root Query and Mutation types. List any types that cannot be auto-detected to ensure they are included in the schema.
```yaml
overblog_graphql:
definitions:
schema:
query: Query
mutation: Mutation
# Types unreachable by static analysis must be listed explicitly
types: [Human, Droid]
```
--------------------------------
### Get Current User
Source: https://github.com/overblog/graphqlbundle/blob/master/docs/definitions/expression-language.md
The `getUser` function retrieves the current user object from the security token storage. It can be used to access user properties.
```yaml
@=getUser()
```
```yaml
@=getUser().firstName === 'adam'
```
--------------------------------
### Configure Annotation Mapping
Source: https://github.com/overblog/graphqlbundle/blob/master/docs/attributes/index.md
Use the `annotation` mapping type in `graphql.yaml` for annotation-based definitions. Ensure `symfony/cache` and `doctrine/annotation` are installed. Note: Annotations are deprecated.
```yaml
overblog_graphql:
definitions:
mappings:
types:
- type: annotation
dir: "%kernel.project_dir%/src/GraphQL"
suffix: ~
```
--------------------------------
### Configure Type Mappings (YAML)
Source: https://github.com/overblog/graphqlbundle/blob/master/docs/definitions/type-system/index.md
Define custom directories and file suffixes for YAML type definitions. Supports multiple types from the same directory.
```yaml
overblog_graphql:
definitions:
mappings:
# auto_discover: false # to disable bundles and root dir auto discover
types:
-
type: yaml # or graphql or annotation null
dir: "%kernel.root_dir%/.../mapping" # sub directories are also searched
# suffix: .types # use to change default file suffix
-
types: [yaml, graphql] # to include different types from the same dir
dir: "%kernel.root_dir%/.../mapping"
```
--------------------------------
### Validation Translation Resource (Structured)
Source: https://github.com/overblog/graphqlbundle/blob/master/docs/validation/index.md
Provide translations for validation messages in a structured YAML format. This example shows translations for username and password validation rules.
```yaml
# translations\validators.en.yaml
register:
username:
length:
min: "The username should have {{ length }} characters or more"
max: "The username should have {{ length }} characters or less"
password:
identical: "The passwords are not equal."
length:
min: "The password should have {{ length }} characters or more"
max: "The password should have {{ length }} characters or less"
```
--------------------------------
### Registering Private Services for Expression Language
Source: https://github.com/overblog/graphqlbundle/blob/master/docs/definitions/expression-language.md
Demonstrates how to tag a private service to make it accessible via the expression language's `service` function. This is necessary because private services are not directly retrievable from the service container.
```yaml
App\MyPrivateService:
public: false
tags:
- { name: overblog_graphql.service, alias: my_private_service }
```
```yaml
MyType:
type: object
config:
fields:
name:
type: String!
resolve: "@=service('my_private_service').formatName(value)"
```
--------------------------------
### Implement Args Builder Class
Source: https://github.com/overblog/graphqlbundle/blob/master/docs/definitions/builders/args.md
Create a PHP class that implements the `MappingInterface` to define the structure and default values for your custom arguments.
```php
[
'type' => 'Int!',
'defaultValue' => $defaultLimit,
],
'offset' => [
'type' => 'Int!',
'defaultValue' => 0,
],
];
}
}
```
--------------------------------
### Customize Field Complexity
Source: https://github.com/overblog/graphqlbundle/blob/master/docs/security/query-complexity-analysis.md
Define custom complexity for specific fields within your GraphQL schema. This example adds a base complexity of 1000 to the `droid` field.
```yaml
#src/MyBundle/Resources/config/graphql/Query.types.yml
Query:
type: object
config:
fields:
droid:
type: "Droid"
complexity: '@=1000 + childrenComplexity'
args:
id:
description: "id of the droid"
type: "String!"
resolve: "@=query('character_droid', args)"
```
--------------------------------
### Define Custom Field Builder in YAML
Source: https://context7.com/overblog/graphqlbundle/llms.txt
Configure a custom field builder in `graphql.yaml` to automatically add fields to your GraphQL types. This example adds timestamp fields.
```yaml
overblog_graphql:
definitions:
builders:
fields:
- alias: "Timestamped"
class: "App\GraphQL\Builder\TimestampFields"
```
--------------------------------
### Basic Resolver Usage
Source: https://github.com/overblog/graphqlbundle/blob/master/docs/helpers/relay-paginator.md
Integrate the Paginator within a resolver to handle data fetching and pagination logic. It requires a data backend and a callback for counting total items.
```php
getData($offset, $limit);
});
return $paginator->auto($args, function() use ($backend) {
return $backend->countAll();
});
}
}
```
--------------------------------
### GraphQL Schema Definition
Source: https://context7.com/overblog/graphqlbundle/llms.txt
Defines GraphQL types, interfaces, enums, and inputs. This example includes a Character interface, Human type, Episode enum, and a CreateCharacterInput for mutations.
```APIDOC
## GraphQL Schema Definition
### Interface: Character
- **id**: ID!
- **name**: String!
- **friends**: [Character]
- **appearsIn**: [Episode]!
### Type: Human (implements Character)
- **id**: ID!
- **name**: String!
- **friends**: [Character]
- **appearsIn**: [Episode]!
- **totalCredits**: Int
### Enum: Episode
- NEWHOPE
- EMPIRE
- JEDI
### Input: CreateCharacterInput
- **name**: String!
### Mutation: RootMutation
- **createCharacter**(character: CreateCharacterInput!): Character!
```
--------------------------------
### GraphQL Schema Compiled Event Subscriber
Source: https://github.com/overblog/graphqlbundle/blob/master/docs/events/index.md
Implement `EventSubscriberInterface` to listen for the `SchemaCompiledEvent` and perform actions when the schema is newly compiled. This example shows a subscriber for schema dumping.
```php
newObject(string $className, array $args = []): object
### Examples
```yaml
@=newObject("App\\Entity\\User", ["John", 15])
# Using inside another function (query)
@=query("myResolver", newObject("App\\User\\User", [args]))
```
```
--------------------------------
### Define a Mutation with Arguments
Source: https://github.com/overblog/graphqlbundle/blob/master/docs/attributes/attributes-reference.md
Define a mutation field within a provider class using `#[GQLield]` and specify its arguments with `#[GQLield]`.
```php
repository->find($id);
$user->setEmail($newEmail);
$this->repository->save($user);
return $user;
}
```
--------------------------------
### Implement Custom Scalar Logic in PHP
Source: https://github.com/overblog/graphqlbundle/blob/master/docs/definitions/type-system/scalars.md
Implement the serialize, parseValue, and parseLiteral methods for a custom scalar type in PHP. This example demonstrates handling DateTime objects.
```php
format('Y-m-d H:i:s');
}
/**
* @param mixed $value
*
* @return \DateTimeInterface
*/
public static function parseValue($value)
{
return new \DateTimeImmutable($value);
}
/**
* @param Node $valueNode
*
* @return \DateTimeInterface
*/
public static function parseLiteral(Node $valueNode)
{
return new \DateTimeImmutable($valueNode->value);
}
}
```
--------------------------------
### Configure GraphiQL JavaScript Libraries
Source: https://github.com/overblog/graphqlbundle/blob/master/UPGRADE.md
When migrating from the old GraphiQL integration, move the JavaScript library versions from `overblog_graphql` to `overblog_graphiql` configuration.
```yaml
overblog_graphql:
- versions:
- graphiql: "0.11"
- react: "15.6"
- fetch: "2.0"
- relay: "classic"
overblog_graphiql:
+ javascript_libraries:
+ graphiql: "0.11"
+ react: "15.6"
+ fetch: "2.0"
```
--------------------------------
### Equivalent Schema Definition (Simple)
Source: https://github.com/overblog/graphqlbundle/blob/master/docs/definitions/builders/field.md
This YAML demonstrates the expanded schema definition equivalent to using the 'RawId' builder without specific configuration, showing the default 'id' name and 'Int!' type.
```yaml
User:
type: object
config:
fields:
rawId:
description: 'The user raw id'
type: 'Int!'
resolve: '@=value.id'
```
--------------------------------
### Configure GraphQL Bundle (Attribute Mapping)
Source: https://context7.com/overblog/graphqlbundle/llms.txt
Configure the bundle to use PHP attributes for defining GraphQL types. Specify the directory where your annotated classes are located.
```yaml
overblog_graphql:
definitions:
mappings:
types:
- type: attribute
dir: "%kernel.project_dir%/src/GraphQL"
suffix: ~
```
--------------------------------
### Mutation Configuration (IntroduceShip)
Source: https://context7.com/overblog/graphqlbundle/llms.txt
YAML configuration for the 'IntroduceShip' mutation, defining its payload, input type, and resolver.
```APIDOC
## Mutation Configuration
### Mutation: IntroduceShip
- **Type**: IntroduceShipPayload!
- **Resolver**: `@=mutation('create_ship', args['input']['shipName'], args['input']['factionId'])`
- **Arguments**:
- **input**: IntroduceShipInput!
### Type: IntroduceShipPayload
- **ship**: Ship
- **faction**: Faction
### Input: IntroduceShipInput
- **shipName**: String!
- **factionId**: String!
```
--------------------------------
### Registering and Using the Upload Scalar Type
Source: https://context7.com/overblog/graphqlbundle/llms.txt
Details the steps to register the `Upload` scalar type for handling file uploads and demonstrates its usage in mutations for single and multiple file uploads.
```yaml
# 1. Register the upload scalar
Upload:
type: custom-scalar
config:
scalarType: '@=newObject("Overblog\\GraphQLBundle\\Upload\\Type\\GraphQLUploadType")'
# 2. Use the scalar in your mutation
Mutation:
type: object
config:
fields:
singleUpload:
type: "String!"
resolve: "@=args['file'].getClientOriginalName()"
args:
file: { type: "Upload!" }
multipleUpload:
type: "[String!]!"
resolve: "@=query('upload_handler', args['files'])"
args:
files: { type: "[Upload!]!" }
```
--------------------------------
### GraphQL Configuration for Validation Linking (Doctrine Entity)
Source: https://github.com/overblog/graphqlbundle/blob/master/docs/validation/index.md
Configure GraphQL to link validation constraints from a Doctrine entity. This example shows linking to the User class, which has a static 'validate' method.
```yaml
Mutation:
type: object
config:
fields:
createUser:
validation: App\Entity\User # linking
resolve: "@=res('createUser', [args])"
# ...
```
--------------------------------
### Access Service with Expression Language
Source: https://github.com/overblog/graphqlbundle/blob/master/docs/definitions/expression-language.md
Use the 'service' function to retrieve a service from the container. The 'serv' alias can also be used. Ensure private services are explicitly tagged if needed. FQCN usage requires careful quoting.
```yaml
@=service('my_service').customMethod()
```
```yaml
# Using the 'serv' alias
@=serv('my_service').customMethod()
```
```yaml
# Using the FQCN for the service name (only works for public services).
# Note the double quotes.
@=serv("App\\Manager\\UserManager").someMethod()
```
```yaml
# If using single quotes, you must use 4 slashes
@=serv('App\\\\Manager\\\\UserManager').someMethod()
```
--------------------------------
### GraphQL Configuration for Validation Linking (Explicit)
Source: https://github.com/overblog/graphqlbundle/blob/master/docs/validation/index.md
Configure GraphQL fields to link to validation constraints defined in a PHP class. This example shows explicit linking to the class, a property, and a getter.
```yaml
Mutation:
type: object
config:
fields:
editPost:
type: Post
resolve: "@=mutation('edit_post', [args])"
validation:
link: App\Entity\Post # targeting the class
args:
title:
type: String!
validation:
link: App\Entity\Post::title # property and getters
text:
type: String!
validation:
link: App\Entity\Post::$text # only property
```
--------------------------------
### Manual Validation in Resolver
Source: https://context7.com/overblog/graphqlbundle/llms.txt
Demonstrates how to manually inject and use the `InputValidator` service within a mutation resolver to perform validation.
```APIDOC
## Manual Validation Example
### Description
This example shows how to use the `InputValidator` service within a mutation resolver to validate input arguments. The validator can be configured to validate specific groups or all default constraints. Validation failures will result in an `ArgumentsValidationException`.
### Resolver Signature
`register(Argument $args, InputValidator $validator): User`
### Validation Usage
- `$validator->validate('registration');` : Validates constraints in the 'registration' group.
- `$validator->validate();` : Validates constraints in the default group.
- `$validator->validate(null, false);` : Returns a `ConstraintViolationList` instead of throwing an exception.
```
--------------------------------
### Apply Timestamped Builder to a GraphQL Type
Source: https://context7.com/overblog/graphqlbundle/llms.txt
Configure a GraphQL `Post` type in YAML to use the `Timestamped` builder. This example shows how to specify custom property names for `createdAt` and `updatedAt`.
```yaml
# Generates createdAt and updatedAt fields on Post
Post:
type: object
config:
builders:
- builder: Timestamped
builderConfig:
propertyCreatedAt: created
propertyUpdatedAt: updated
fields:
title: { type: "String!" }
```
--------------------------------
### Use Upload Scalar in Schema (YAML)
Source: https://github.com/overblog/graphqlbundle/blob/master/docs/definitions/upload-files.md
Utilize the defined upload scalar type in your GraphQL schema mutations. This example shows how to define arguments for single and multiple file uploads.
```yaml
Mutation:
type: object
config:
fields:
singleUpload:
type: String!
resolve: '@=args["file"].getBasename()'
args:
file: MyUpload!
multipleUpload:
type: '[String!]'
resolve: '@=[args["files"][0].getBasename(), args["files"][1].getBasename()]'
args:
files: '[MyUpload!]!'
```
--------------------------------
### Create New Object Instance
Source: https://github.com/overblog/graphqlbundle/blob/master/docs/definitions/expression-language.md
Use `newObject` to create a new class instance with specified arguments. This function utilizes PHP's Reflection API.
```yaml
@=newObject("App\\Entity\\User", ["John", 15])
```
```yaml
@=query("myResolver", newObject("App\\User\\User", [args]))
```
--------------------------------
### Define a Custom Resolver Map
Source: https://github.com/overblog/graphqlbundle/blob/master/docs/definitions/resolver-map.md
Extend the ResolverMap class to define custom resolvers for your GraphQL schema. This example shows how to map fields for Query, Object, and custom scalar types.
```php
[
self::RESOLVE_FIELD => function ($value, ArgumentInterface $args, \ArrayObject $context, ResolveInfo $info) {
if ('baz' === $info->fieldName) {
$id = (int) $args['id'];
return findBaz('baz', $id);
}
return null;
},
'bar' => [Bar::class, 'getBar'],
],
'Foo' => [
self::RESOLVE_TYPE => function ($value) {
return isset($value['user']) ? 'Bar' : null;
},
],
// enum internal values
'User' => [
'TATA' => 1,
'TITI' => 2,
'TOTO' => 3,
],
// custom scalar
'Baz' => [
self::SERIALIZE => function ($value) {
return sprintf('%s Formatted Baz', $value);
},
self::PARSE_VALUE => function ($value) {
if (!is_string($value)) {
throw new Error(sprintf('Cannot represent following value as a valid Baz: %s.', Utils::printSafeJson($value)));
}
return str_replace(' Formatted Baz', '', $value);
},
self::PARSE_LITERAL => function ($valueNode) {
if (!$valueNode instanceof StringValueNode) {
throw new Error('Query error: Can only parse strings got: '.$valueNode->kind, [$valueNode]);
}
return str_replace(' Formatted Baz', '', $valueNode->value);
},
],
// or reuse an existing scalar (note: description and name will be override by decorator)
//'Baz' => [self::SCALAR_TYPE => function () { return new FooScalarType(); }],
];
}
}
```
--------------------------------
### Enrich Error Objects with Custom Codes
Source: https://context7.com/overblog/graphqlbundle/llms.txt
Listen to the `graphql.error_formatting` event to modify how errors are formatted in the response. This example adds a custom 'code' field to errors, derived from the previous exception or the error itself.
```php
getError();
$code = $error->getPrevious() ? $error->getPrevious()->getCode() : $error->getCode();
$event->getFormattedError()->offsetSet('code', $code);
}
}
// Response errors[]: { "message": "...", "code": 404, "category": "user" }
```
```yaml
App\EventListener\ErrorCode:
tags:
- { name: kernel.event_listener, event: graphql.error_formatting, method: onErrorFormatting }
```
--------------------------------
### Configure GraphQL Bundle (Single Endpoint)
Source: https://context7.com/overblog/graphqlbundle/llms.txt
Configure the bundle to use YAML for schema definitions and set up a single GraphQL endpoint in your Symfony application.
```yaml
overblog_graphql:
definitions:
schema:
query: Query
mutation: Mutation
mappings:
types:
-
type: yaml
dir: "%kernel.project_dir%/config/graphql/types"
suffix: ~
```
```yaml
overblog_graphql_single_endpoint:
resource: "@OverblogGraphQLBundle/Resources/config/routing/single.yaml"
prefix: /
```
--------------------------------
### Create Promise with ReactPHP/Promise
Source: https://github.com/overblog/graphqlbundle/blob/master/docs/data-fetching/promise.md
Instantiate a native ReactPHP Promise directly within your resolver. This approach is suitable when using the ReactPHP/Promise adapter.
```php
'Luke']);
});
}
}
```
--------------------------------
### Update Resolver Interface Import
Source: https://github.com/overblog/graphqlbundle/blob/master/UPGRADE.md
Shows the necessary change in import statements when renaming ResolverInterface to QueryInterface.
```diff
- use Overblog\GraphQLBundle\Definition\Resolver\ResolverInterface;
+ use Overblog\GraphQLBundle\Definition\Resolver\QueryInterface;
- class UserResolver implements ResolverInterface
+ class UserQuery implements QueryInterface
{
// ...
}
```