Internal GraphQL Server
Internal GraphQL ServerInternal GraphQL Server

Internal GraphQL Server

Included in the “Power Extensions” bundle

Cette extension installe un serveur GraphQL interne, qui peut être invoqué dans votre application en utilisant du code PHP.

Parmi d'autres cas d'utilisation, vous pouvez déclencher l'exécution d'une requête GraphQL lorsqu'une action se produit, pour effectuer une tâche associée (comme envoyer une notification, ajouter une entrée dans les logs, valider une condition, etc).

Description

Le serveur GraphQL interne est accessible via la classe GatoGraphQL\InternalGraphQLServer\GraphQLServer, à travers ces trois méthodes :

  • executeQuery : Exécute une requête GraphQL
  • executeQueryInFile : Exécute une requête GraphQL contenue dans un fichier (.gql)
  • executePersistedQuery : Exécute une persisted query GraphQL (en fournissant son ID en tant qu'int, ou son slug en tant que string) (l'extension Persisted Queries est requise)

Voici les signatures des méthodes :

namespace GatoGraphQL\InternalGraphQLServer;
 
use PoP\Root\HttpFoundation\Response;
 
class GraphQLServer {
  /**
   * Execute a GraphQL query
   */
  public static function executeQuery(
    string $query,
    array $variables = [],
    ?string $operationName = null,
    int|string|null $schemaConfigurationIDOrSlug = null,
  ): Response {
    // ...
  }
 
 
  /**
   * Execute a GraphQL query contained in a (`.gql`) file
   */
  public static function executeQueryInFile(
    string $file,
    array $variables = [],
    ?string $operationName = null,
    int|string|null $schemaConfigurationIDOrSlug = null,
  ): Response {
    // ...
  }
 
 
  /**
   * Execute a persisted GraphQL query (providing its object
   * of type WP_Post, ID as an int, or slug as a string)
   */
  public static function executePersistedQuery(
    WP_Post|string|int $persistedQuery,
    array $variables = [],
    ?string $operationName = null
  ): Response {
    // ...
  }
}

Pour exécuter une requête GraphQL et obtenir le contenu de la réponse :

// Provide the GraphQL query
$query = "{ ... }";
 
// Execute the query against the internal server
$response = GraphQLServer::executeQuery($query);
 
// Get the content and decode it
$responseContent = json_decode($response->getContent(), true);
 
// Access the data and errors from the response
$responseData = $responseContent["data"] ?? [];
$responseErrors = $responseContent["errors"] ?? [];

L'objet Response contient également tout header produit (par exemple : si une Cache Control List a été appliquée, elle ajouterait le header Cache-Control) :

$responseHeaders = $response->getHeaders();
$responseCacheControlHeader = $response->getHeaderLine('Cache-Control');

Notez que la classe GraphQLServer n'est pas prête avant le hook init du cœur de WordPress.

Configuration du schéma

Le Internal GraphQL Server applique sa propre Configuration du schéma. Par exemple, la configuration par défaut est sélectionnée dans la page des Réglages, sous l'onglet "Internal GraphQL Server".

Configuration du Internal GraphQL Server dans les Réglages

Cette configuration s'applique également chaque fois que la requête exécutée contre le internal GraphQL server a été déclenchée par une autre requête GraphQL pendant sa résolution dans un endpoint avec une configuration différente (comme l'endpoint public graphql/).

Pour illustrer, supposons que nous ayons configuré l'endpoint unique graphql/ pour appliquer une Liste de Contrôle d'Accès afin de valider les utilisateurs par IP, et que nous exécutions la mutation createPost contre cet endpoint :

mutation {
  createPost(input: {...}) {
    # ...
  }
}

Ainsi, seuls les visiteurs depuis cette IP pourront exécuter cette mutation.

Ensuite, il y a un hook sur publish_post qui exécute une requête contre le internal GraphQL server (par exemple : pour envoyer une notification à l'administrateur du site) :

add_action(
  "publish_post",
  fn (int $post_id) => GraphQLServer::executeQuery("...", ["postID" => $post_id])
);

Cette requête GraphQL sera résolue en utilisant la configuration du schéma appliquée au internal GraphQL server, et non à l'endpoint unique graphql/.

Par conséquent, la validation par IP d'utilisateur n'aura pas lieu (sauf si cette Liste de Contrôle d'Accès a également été appliquée au internal GraphQL server).

Débogage des problèmes

Pour suivre l'exécution de la requête, nous pouvons parcourir les logs.

Consultez Résolution des problèmes pour plus de détails.

Exemple

Dans ce flux de travail exemple (qui utilise également les modules Multiple Query Execution, Helper Function Collection et Field to Input), lorsqu'un nouvel article est créé sur le site, nous envoyons une notification à l'utilisateur administrateur.

Nous nous accrochons à l'action du cœur de WordPress new_to_publish, récupérons les données de l'article nouvellement créé, et appelons GraphQLServer::executeQuery :

add_action(
  'new_to_publish',
  function (WP_Post $post) {
    if ($post->post_type !== 'post') {
      return;
    }
    // Check the contents of the query below
    $query = ' ... ';
    $variables = [
      'postTitle' => $post->post_title,
      'postContent' => $post->post_content,
    ]
    GraphQLServer::executeQuery($query, $variables, 'SendEmail');
  }
);

...avec cette requête GraphQL :

query GetEmailData(
  $postTitle: String!,
  $postContent: String!
) {
  emailMessageTemplate: _strConvertMarkdownToHTML(
    text: """
 
There is a new post on the site: 
 
**{$postTitle}**:
 
{$postContent}
 
    """
  )
  emailMessage: _strReplaceMultiple(
    search: ["{$postTitle}", "{$postContent}"],
    replaceWith: [$postTitle, $postContent],
    in: $__emailMessageTemplate
  )
    @export(as: "emailMessage")
}
 
mutation SendEmail @depends(on: "GetEmailData") {
  _sendEmail(
    input: {
      to: "admin@site.com"
      subject: "There is a new post"
      messageAs: {
        html: $emailMessage
      }
    }
  ) {
    status
  }
}