Archives: Functions

  • register_graphql_scalar

    Given a config array for a custom Scalar, this registers a Scalar for use in the Schema

    register_graphql_scalar( string $type_name, array $config );

    Per the GraphQL Spec, WPGraphQL provides several built-in scalar types.

    • Boolean
    • Float
    • Integer
    • ID
    • String

    This function is used to define new Scalars to the Schema. Some common cases are Url, Email, Date, and others.

    Note: Future versions of WPGraphQL will likely support some custom Scalars out of the box. Stay tuned!

    Parameters

    • $type_name (string): The name of the type to register
    • $config (array): Configuration for the field
      • $description (string): Description of the scalar. This will be used to self-document the schema and should describe how the scalar type should be used.
      • $serialize (function): A function used to serialize the value of the scalar. Serializes an internal value to include in a response.
      • $parseValue (function): A function used to parse the value of the scalar. Parses an externally provided value (query variable) to use as an input.
      • $parseLiteral (function): A function used to parse the value of the scalar. Parses an externally provided literal value (hardcoded in GraphQL query) to use as an input.

    Source

    File: access-functions.php

    Example

    WPGraphQL ships with the out-of-the-box Scalars that are supported with GraphQL, however, it’s possible to define your own custom Scalars.

    In order to register your own Scalar, you should understand how scalars are presented in GraphQL. GraphQL deals with scalars in following cases:

    1. When converting internal representation of value returned by your app (e.g. stored in a database or hardcoded in the source code) to serialized representation included in the response.
    2. When converting input value passed by a client in variables along with GraphQL query to internal representation of your app.
    3. When converting input literal value hardcoded in GraphQL query (e.g. field argument value) to the internal representation of your app.

    In this example, we register a scalar called Email.

    register_graphql_scalar( 'Email', [
    	'description' => __( 'Email according to the email spec', 'wp-graphql' ),
    	/**
             * Serializes an internal value to include in a response.
             *
             * @param string $value
             * @return string
             */
            'serialize' => function( $value ) {
    			return $value;
    	},
            /**
             * Parses an externally provided value (query variable) to use as an input
             *
             * @param mixed $value
             * @return mixed
             */
    	'parseValue' => function( $value ) {
    		if ( ! filter_var( $value, FILTER_VALIDATE_EMAIL ) ) {
    			throw new Error( "Cannot represent following value as email: " . GraphQLUtilsUtils::printSafeJson( $value ) );
    		}
    		return $value;
    	},
            /**
             * Parses an externally provided literal value (hardcoded in GraphQL query) to use as an input.
             * 
             * E.g. 
             * {
             *   user(email: "user@example.com") 
             * }
             *
             * @param GraphQLLanguageASTNode $valueNode
             * @param array|null $variables
             * @return string
             * @throws Error
             */
    	'parseLiteral' => function( $valueNode, array $variables = null ) {
    		// Note: throwing GraphQLErrorError vs UnexpectedValueException to benefit from GraphQL
    		// error location in query:
    		if ( ! $valueNode instanceof GraphQLLanguageASTStringValueNode ) {
    			throw new Error( 'Query error: Can only parse strings got: ' . $valueNode->kind, [$valueNode] );
    		}
    		if ( ! filter_var($valueNode->value, FILTER_VALIDATE_EMAIL ) ) {
    			throw new Error( "Not a valid email", [ $valueNode ] );
    		}
    		return $valueNode->value;
    	}
    ]);

    In order to view this new Scalar type, a new field can be registered.

    register_graphql_field( 'RootQuery', 'testEmail', [
    	'type' => 'Email',
    	'description' => __( 'Testing custom scalars', 'wp-graphql' ),
    	'resolve' => function() {
    		return 'testemail@mac.com';
    	},
    ]);

    This new field can now be queried:

    {
      testEmail
    }

    Which will result in the following data to be returned:

    {
      "data": {
        "testEmail": "testemail@mac.com"
      }
    }

    This new field and Scalar type can be viewed in the GraphiQL documentation:

  • deregister_graphql_field

    Given a Type Name and Field Name, this removes the field from the TypeRegistry

    deregister_graphql_field( string $type_name, string $field_name );

    Parameters

    • $type_name (string): The Type Name
    • $field_name (string): The Field Name to remove from the TypeRegistry

    Source

    File: access-functions.php

    Examples

    Below is an example of removing the commentCount field from the Post type. First the comment count can be seen on the Post type in the below GraphiQL example:

    Example showing the commentCount field is available on the Post type

    Now we can use the deregister_graphql_field function to remove this field from the Post type.

    add_action( 'graphql_register_types', 'example_extend_wpgraphql_schema' );
    
    function example_extend_wpgraphql_schema($type_registry) {
    	deregister_graphql_field( 'Post', 'commentCount' );
    }

    Now this field is no longer available to be queried and results in a GraphQL error.

  • register_graphql_mutation

    Given a Mutation Name and Config array, this adds a Mutation to the Schema

    register_graphql_mutation( string $mutation_name, array $config );

    Parameters

    • $mutation_name (string): The name of the mutation
    • $config (array): Configuration for the mutation
      • $description (string): Description of the mutation type.
      • $inputFields (array): The input fields for the mutation
        • $type (string): The name of the Type in the Schema the field should accept. Note: ObjectTypes cannot be used as Input Types.
        • $description (string): The field description.
      • $outputFields (array): The output field for the mutation (what can be asked for in response)
      • $mutateAndGetPayload (function): How the mutation should resolve

    Source

    File: access-functions.php

    Example

    Here is a basic example of registering a mutation:

    # This function registers a mutation to the Schema.
    # The first argument, in this case `exampleMutation`, is the name of the mutation in the Schema
    # The second argument is an array to configure the mutation.
    # The config array accepts 3 key/value pairs for: inputFields, outputFields and mutateAndGetPayload.
    register_graphql_mutation( 'exampleMutation', [
    
    	# inputFields expects an array of Fields to be used for inputting values to the mutation
    	'inputFields'         => [
    		'exampleInput' => [
    			'type' => 'String',
    			'description' => __( 'Description of the input field', 'your-textdomain' ),
    		]
    	],
    
    	# outputFields expects an array of fields that can be asked for in response to the mutation
    	# the resolve function is optional, but can be useful if the mutateAndPayload doesn't return an array
    	# with the same key(s) as the outputFields
    	'outputFields'        => [
    		'exampleOutput' => [
    			'type' => 'String',
    			'description' => __( 'Description of the output field', 'your-textdomain' ),
    			'resolve' => function( $payload, $args, $context, $info ) {
                       		return isset( $payload['exampleOutput'] ) ? $payload['exampleOutput'] : null;
    			}
    		]
    	],
    
    	# mutateAndGetPayload expects a function, and the function gets passed the $input, $context, and $info
    	# the function should return enough info for the outputFields to resolve with
    	'mutateAndGetPayload' => function( $input, $context, $info ) {
    		// Do any logic here to sanitize the input, check user capabilities, etc
    		$exampleOutput = null;
    		if ( ! empty( $input['exampleInput'] ) ) {
    			$exampleOutput = 'Your input was: ' . $input['exampleInput'];
    		}
    		return [
    			'exampleOutput' => $exampleOutput,
    		];
    	}
    ] );

    Registering the above mutation would allow for the following mutation to be executed:

    mutation {
    	exampleMutation(
    		input: { clientMutationId: "example", exampleInput: "Test..." }
    	) {
    		clientMutationId
    		exampleOutput
    	}
    }

    And the following response would be provided:

    {
    	"data": {
    		"exampleMutation": {
    			"clientMutationId": "example",
    			"exampleOutput": "Your input was: Test..."
    		}
    	}
    }
  • graphql

    Given an array with a Query and optional Variables and Operation Name this executes a GraphQL request.

    graphql( $operation );

    Paramaters

    • $operation (array): An associative array of key/value pairs for the operation to execute.
      • $query (string): The Query string to execute. This can be a mutation as well.
      • $variables (array): Array of variables to be used with the operation
      • $operation_name (string): The name of the operation.

    Source

    File: access-functions.php

    Examples

    The graphql() function can be used to execute GraphQL operations within PHP. WPGraphQL uses this method heavily within it’s automated test suites.

    Query a List of Posts in PHP

    Here’s an example of querying a list of posts using the graphql() function:

    $graphql = graphql([
      'query' => '
      {
        posts {
          nodes {
            id
            title
          }
        }
      }
      '
    ]);

    Query with Arguments in PHP

    Here’s an example of querying with arguments in PHP.

    $graphql = graphql([
      'query' => '
      query GetPosts( $first: Int ) {
        posts {
          nodes {
            id
            title
          }
        }
      }
      ',
      'variables' => [
        'first' => 5, // <-- This value could be dynamic from a shortcode/gutenberg block, a form submission, etc.
      ],
    ]);