Add as Composer dependency:
composer require simpod/graphql-utilsInstead of defining your schema as an array, use can use more objective-oriented approach. This library provides set of strictly typed builders that help you build your schema:
- EnumBuilder
- FieldBuilder
- InputFieldBuilder
- InputObjectBuilder
- InterfaceBuilder
- ObjectBuilder
- TypeBuilder
- UnionBuilder
✔️ Standard way with webonyx/graphql-php
<?phpuseGraphQL\Type\Definition\ObjectType;
useGraphQL\Type\Definition\ResolveInfo;
$userType = newObjectType([
'name' => 'User',
'description' => 'Our blog visitor',
'fields' => [
'firstName' => [
'type' => Type::string(),
'description' => 'User first name'
],
'email' => Type::string()
],
'resolveField' => staticfunction(User$user, $args, $context, ResolveInfo$info) {
switch ($info->fieldName) {
case'name':
return$user->getName();
case'email':
return$user->getEmail();
default:
returnnull;
}
}
]);✨ The same can be produced in objective way
<?phpuseGraphQL\Type\Definition\ObjectType;
useGraphQL\Type\Definition\ResolveInfo;
useSimPod\GraphQLUtils\Builder\ObjectBuilder;
$userType = newObjectType(
ObjectBuilder::create('User')
->setDescription('Our blog visitor')
->setFields([
FieldBuilder::create('firstName', Type::string())
->setDescription('User first name')
->build(),
FieldBuilder::create('email', Type::string())->build(),
])
->setFieldResolver(
staticfunction(User$user, $args, $context, ResolveInfo$info) {
switch ($info->fieldName) {
case'name':
return$user->getName();
case'email':
return$user->getEmail();
default:
returnnull;
}
}
)
->build()
);✔️ Standard way with webonyx/graphql-php
<?phpuseGraphQL\Type\Definition\EnumType;
$episodeEnum = newEnumType([
'name' => 'Episode',
'description' => 'One of the films in the Star Wars Trilogy',
'values' => [
'NEWHOPE' => [
'value' => 4,
'description' => 'Released in 1977.'
],
'EMPIRE' => [
'value' => 5,
'description' => 'Released in 1980.'
],
'JEDI' => [
'value' => 6,
'description' => 'Released in 1983.'
],
]
]);✨ The same can be produced in objective way
<?phpuseGraphQL\Type\Definition\EnumType;
useSimPod\GraphQLUtils\Builder\EnumBuilder;
$episodeEnum = newEnumType( EnumBuilder::create('Episode')
->setDescription('One of the films in the Star Wars Trilogy')
->addValue(4, 'NEWHOPE', 'Released in 1977.')
->addValue(5, 'EMPIRE', 'Released in 1980.')
->addValue(6, 'JEDI', 'Released in 1983.')
->build()
);✔️ Standard way with webonyx/graphql-php
<?phpuseGraphQL\Type\Definition\InterfaceType;
useGraphQL\Type\Definition\Type;
$character = newInterfaceType([
'name' => 'Character',
'description' => 'A character in the Star Wars Trilogy',
'fields' => [
'id' => [
'type' => Type::nonNull(Type::string()),
'description' => 'The id of the character.',
],
'name' => [
'type' => Type::string(),
'description' => 'The name of the character.'
]
],
'resolveType' => staticfunction ($value) : object {
if ($value->type === 'human') {
return MyTypes::human(); }
return MyTypes::droid();
}
]);✨ The same can be produced in objective way
<?phpuseGraphQL\Type\Definition\InterfaceType;
useGraphQL\Type\Definition\Type;
useSimPod\GraphQLUtils\Builder\InterfaceBuilder;
useSimPod\GraphQLUtils\Builder\FieldBuilder;
$character = newInterfaceType(
InterfaceBuilder::create('Character')
->setDescription('A character in the Star Wars Trilogy')
->setFields([
FieldBuilder::create('id', Type::nonNull(Type::string()))
->setDescription('The id of the character.')
->build(),
FieldBuilder::create('name', Type::string())
->setDescription('The name of the character.')
->build()
])
->setResolveType(
staticfunction ($value) : object {
if ($value->type === 'human') {
return MyTypes::human(); }
return MyTypes::droid();
}
)
->build()
);✔️ Standard way with webonyx/graphql-php
<?phpuseGraphQL\Type\Definition\UnionType;
$searchResultType = newUnionType([
'name' => 'SearchResult',
'types' => [
MyTypes::story(),
MyTypes::user()
],
'resolveType' => staticfunction($value) {
if ($value->type === 'story') {
return MyTypes::story(); }
return MyTypes::user();
}
]);✨ The same can be produced in objective way
<?phpuseSimPod\GraphQLUtils\Builder\UnionBuilder;
$character = newUnionType(
UnionBuilder::create('SearchResult')
->setTypes([
MyTypes::story(),
MyTypes::user()
])
->setResolveType(
staticfunction($value) {
if ($value->type === 'story') {
return MyTypes::story(); }
return MyTypes::user();
}
)
->build()
);scalar type that produces scalar DateTime in your schema.
SimPod\GraphQLUtils\Type\DateTimeType
Extending your exception with SimPod\GraphQLUtils\Error\Error forces you to implement getType() method.
Example Error class
<?phpuseSimPod\GraphQLUtils\Error\Error;
finalclass InvalidCustomerIdProvided extends Error
{
privateconstTYPE = 'INVALID_CUSTOMER_ID_PROVIDED';
publicstaticfunctionnoneGiven() : self
{
returnnewself('No CustomerId provided');
}
publicfunctiongetType() : string
{
returnself::TYPE;
}
publicfunctionisClientSafe() : bool
{
returntrue;
}
}Create your formatter
<?phpuseGraphQL\Error\Error;
useSimPod\GraphQLUtils\Error\FormattedError;
$formatError = staticfunction (Error$error) : array
{
if (! $error->isClientSafe()) {
// eg. log error
}
return FormattedError::createFromException($error);
};
$errorFormatterCallback = staticfunction (Error$error) use ($formatError) : array {
return$formatError($error);
};
$config = GraphQL::executeQuery(/* $args */)
->setErrorFormatter($errorFormatterCallback)
->setErrorsHandler(
staticfunction (array$errors, callable$formatter) : array {
returnarray_map($formatter, $errors);
}
);Error types will then be provided in your response so client can easier identify the error type
{
"errors": [
{
"message": "No CustomerId provided",
"extensions": {
"type": "INVALID_CUSTOMER_ID_PROVIDED",
"category": "validation"
}
}
]
}