Kind of figured it out. It’s possible to extend existing schema with custom properties that will have their own callbacks-resolvers. Reference to custom types in the documentation.
Place this class to your functions.php
class GQLRegister
{
var $itemName = null;
var $itemProps = null;
var $responseName = null;
var $responseParams = null;
var $responseParamsFunction = null;
function __construct(
$itemName,
$itemProps,
$responseName,
$responseParams,
$responseParamsFunction) {
$this->itemName = $itemName;
$this->itemProps = $itemProps;
$this->responseName = $responseName;
$this->responseParams = $responseParams;
$this->responseParamsFunction = $responseParamsFunction;
add_action('graphql_register_types', [ $this, 'setItemType' ]);
add_action('graphql_register_types', [ $this, 'setResponseType' ]);
add_action('graphql_register_types', [ $this, 'setResponseParamsType' ]);
}
function setItemType() {
register_graphql_object_type($this->itemName, [ 'fields' => $this->itemProps ]);
}
function setResponseType() {
register_graphql_object_type($this->responseName, [
'fields' => [
'count' => [ 'type' => 'Integer' ],
'items' => [ 'type' => [ 'list_of' => $this->itemName ]],
'errors' => [ 'type' => [ 'list_of' => 'String' ]]
]
]);
}
function setResponseParamsType() {
register_graphql_field('RootQuery', $this->responseName, [
'type' => $this->responseName,
'args' => $this->responseParams,
'resolve' => $this->responseParamsFunction
]);
}
}
Call constructor of this class with the following parameters.
new GQLRegister(
'CustomUser', // define fields of a single object
[
'id' => [ 'type' => 'Integer' ],
'name' => [ 'type' => 'String' ]
],
'CustomUserResponse',
[ // define input parameters for new property
'page' => [ 'type' => 'Integer' ],
'count' => [ 'type' => 'Integer' ]
],
function($root, $args, $context, $info) { // extract data from DB in this method
// $users = get_users($args);
return [
'count' => 1, // count($users)
'items' => [[ 'name' => 'Demo User' ]] // $users
];
}
);
Now, WPGraphQL shows new property on the query customUserResponse that can return the following structure.
{
"data": {
"customUserResponse": {
"count": 1,
"items": [
{
"name": "Demo User"
}
]
}
}
}