Internal GraphQL Server
Internal GraphQL ServerInternal GraphQL Server

Internal GraphQL Server

Included in the “Power Extensions” bundle

Questa estensione installa un server GraphQL interno, che può essere invocato all'interno della tua applicazione utilizzando codice PHP.

Tra gli altri casi d'uso, puoi attivare l'esecuzione di una query GraphQL ogni volta che si verifica un'azione, per eseguire un'attività correlata (come inviare una notifica, aggiungere una voce nei log, validare una condizione, ecc).

Descrizione

Il server GraphQL interno è accessibile tramite la classe GatoGraphQL\InternalGraphQLServer\GraphQLServer, attraverso questi tre metodi:

  • executeQuery: Esegue una query GraphQL
  • executeQueryInFile: Esegue una query GraphQL contenuta in un file (.gql)
  • executePersistedQuery: Esegue una persisted query GraphQL (fornendo il suo ID come int, o il suo slug come string) (è richiesta l'estensione Persisted Queries)

Queste sono le firme dei metodi:

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 {
    // ...
  }
}

Per eseguire una query GraphQL e ottenere il contenuto della risposta:

// 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'oggetto Response contiene anche qualsiasi header prodotto (ad esempio: se è stata applicata una Cache Control List, aggiungerebbe l'header Cache-Control):

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

Nota che la classe GraphQLServer non è pronta prima dell'hook init del core di WordPress.

Configurazione dello schema

L'Internal GraphQL Server applica la propria Configurazione dello schema. Ad esempio, quella predefinita viene selezionata nella pagina delle Impostazioni, sotto la scheda "Internal GraphQL Server".

Configurazione dell'Internal GraphQL Server nelle Impostazioni

Questa configurazione si applica anche ogni volta che la query eseguita contro l'internal GraphQL server è stata attivata da un'altra query GraphQL mentre veniva risolta in un endpoint con una configurazione diversa (come l'endpoint pubblico graphql/).

Per illustrare, supponiamo di aver configurato l'endpoint singolo graphql/ per applicare una Access Control List allo scopo di validare gli utenti tramite IP, e di eseguire la mutation createPost contro questo endpoint:

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

In questo modo, solo i visitatori provenienti da quell'IP potranno eseguire questa mutation.

Poi c'è un hook su publish_post che esegue una query contro l'internal GraphQL server (ad esempio: per inviare una notifica all'amministratore del sito):

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

Questa query GraphQL verrà risolta utilizzando la configurazione dello schema applicata all'internal GraphQL server, e non all'endpoint singolo graphql/.

Di conseguenza, la validazione tramite IP dell'utente non avrà luogo (a meno che quella Access Control List non sia stata applicata anche all'internal GraphQL server).

Debug dei problemi

Per tracciare l'esecuzione della query, possiamo consultare i log.

Consulta Risoluzione dei problemi per maggiori dettagli.

Esempio

In questo flusso di lavoro di esempio (che utilizza anche i moduli Multiple Query Execution, Helper Function Collection e Field to Input), quando un nuovo articolo viene creato nel sito, inviamo una notifica all'utente amministratore.

Ci agganciamo all'azione del core di WordPress new_to_publish, recuperiamo i dati dall'articolo appena creato e chiamiamo 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');
  }
);

...con questa query 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
  }
}