forked from overblog/GraphQLBundle
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add Input Builder feature. Rename InputType to Input. Tests + docs.
- Loading branch information
Showing
20 changed files
with
594 additions
and
99 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
# The Input Builder service | ||
|
||
When using annotation, as we use classes to describe our GraphQL objects, it is also possible to create and populate classes instances using GraphQL data. | ||
If a class is used to describe a GraphQL Input, this same class can be instanciated to hold the corresponding GraphQL Input data. | ||
This is where the `Input Builder` comes into play. Knowing the matching between GraphQL types and PHP classes, the service is able to instanciate a PHP classes and populate it with data based on the corresponding GraphQL type. | ||
To invoke the Input Builder, we use the `input` expression function in our resolvers. | ||
|
||
## the `input` function in expression language | ||
|
||
The `input` function take two parameter, a GraphQL type (in GraphQL notation, eventually with the "[]" and "!") and a variable containing data. | ||
This function will use the `Input Builder` service to create an instance of the PHP class matching the GraphQL type if it has one and using a property accessor, it will populate the instance, and will use the `validator` service to validate it. | ||
The transformation is done recursively. If an Input include another Input as field, it will also be populated the same way. | ||
|
||
For example: | ||
|
||
```php | ||
namespace App\GraphQL\Input; | ||
|
||
use Overblog\GraphQLBundle\Annotation as GQL; | ||
use Symfony\Component\Validator\Constraints as Assert; | ||
|
||
/** | ||
* @GQL\Input | ||
*/ | ||
class UserRegisterInput { | ||
/** | ||
* @GQL\Field(type="String!") | ||
* @Assert\NotBlank | ||
* @Assert\Length(min = 2, max = 50) | ||
*/ | ||
public $username; | ||
|
||
/** | ||
* @GQL\Field(type="String!") | ||
* @Assert\NotBlank | ||
* @Assert\Email | ||
*/ | ||
public $email; | ||
|
||
/** | ||
* @GQL\Field(type="String!") | ||
* @Assert\NotBlank | ||
* @Assert\Length( | ||
* min = 5, | ||
* minMessage="The password must be at least 5 characters long." | ||
* ) | ||
*/ | ||
public $password; | ||
|
||
/** | ||
* @GQL\Field(type="Int!") | ||
* @Assert\NotBlank | ||
* @Assert\GreaterThan(18) | ||
*/ | ||
public $age; | ||
} | ||
|
||
.... | ||
|
||
/** | ||
* @GQL\Provider | ||
*/ | ||
class UserRepository { | ||
/** | ||
* @GQL\Mutation | ||
*/ | ||
public function createUser(UserRegisterInput $input) : User { | ||
// Use the validated $input here | ||
$user = new User(); | ||
$user->setUsername($input->username); | ||
$user->setPassword($input->password); | ||
... | ||
} | ||
} | ||
``` | ||
|
||
When this Input is used in a mutation, the Symfony service `overblog_graphql.input_builder` is called in order to transform the received array of data into a `UserRegisterInput` instance using a property accessor. | ||
Then the `validator` service is used to validate this instance against the configured constraints. | ||
The mutation received the valid instance. | ||
|
||
In the above example, everything is auto-guessed and a Provider is used. But this would be the same as : | ||
|
||
```php | ||
/** | ||
* @GQL\Type | ||
*/ | ||
class RootMutation { | ||
/** | ||
* @GQL\Field( | ||
* type="User", | ||
* args={ | ||
* @GQL\Arg(name="input", type="UserRegisterInput") | ||
* }, | ||
* resolve="@=service('UserRepository').createUser(input(arg['input']))" | ||
* ) | ||
*/ | ||
public $createUser; | ||
} | ||
``` | ||
|
||
So, the resolver (the `createUser` method) will receive an instance of the class `UserRegisterInput` instead of an array of data. | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.