Gato GraphQL ohne WordPress ausführen
Gato GraphQL wurde mit eigenständigen PHP-Komponenten erstellt, die über Composer verwaltet werden, sodass alle PHP-Komponenten, die den GraphQL-Server ausmachen, nicht von WordPress abhängig sind!
Daher kann der GraphQL-Server als eigenständige PHP-Anwendung ausgeführt werden, und du kannst ihn in jede PHP-Anwendung einbinden, die auf WordPress oder irgendetwas anderem basiert.
Wenn deine Anwendung für einen bestimmten Anwendungsfall nicht auf WordPress-Daten zugreifen muss, bist du zumindest für diesen Anwendungsfall bereit loszulegen.
Dieses Video zeigt einen solchen Anwendungsfall: Interaktion mit der GitHub-API, um Artefakte aus GitHub Actions während der Entwicklung herunterzuladen/zu installieren:
Im Video führt die GraphQL-query eine HTTP-Anfrage aus, um die neuesten Gato GraphQL-Plugins abzurufen, die in GitHub Actions generiert wurden und beim Mergen eines Pull Requests als Artefakte hochgeladen werden.
Die URLs der Artefakte aus der GraphQL-Antwort werden dann in WP-CLI injiziert, damit die Plugins automatisch auf einem lokalen DEV-Webserver installiert werden, um Tests auszuführen.
In diesem Anwendungsfall, da überhaupt keine WordPress-Daten abgerufen werden, kann der GraphQL-Server bereits als eigenständige PHP-App ausgeführt werden.
Im Detail: Gato GraphQL als eigenständige PHP-App ausführen
Hier ist die detaillierte Erklärung des Demo-Videos.
Wir stellen die auszuführende GraphQL-query in der Datei retrieve-github-artifacts.gql bereit.
Die query verbindet sich mit der GitHub-API, indem sie das Zugriffstoken aus der Umgebungsvariable GITHUB_ACCESS_TOKEN holt. Sie generiert dynamisch den vollständigen Pfad für den actions/artifacts-Endpunkt aus den bereitgestellten Variablen und sendet dann eine HTTP-Anfrage dagegen.
Aus der Antwort extrahiert sie dann die „Download-URL" aus jedem Artefakt-Element und sendet asynchrone HTTP-Anfragen dagegen. Aus dem Location-Header jeder dieser „Download-URLs" erhalten wir die tatsächliche URL der herunterladbaren Datei.
Schließlich gibt sie alle URLs zusammen, durch ein Leerzeichen getrennt, aus, um die Injektion in WP-CLI zu erleichtern.
# File retrieve-github-artifacts.gql
query RetrieveProxyArtifactDownloadURLs(
$repoOwner: String!
$repoProject: String!
$perPage: Int = 1
$artifactName: String = ""
) {
githubAccessToken: _env(name: "GITHUB_ACCESS_TOKEN")
@remove
# Create the authorization header to send to GitHub
authorizationHeader: _sprintf(
string: "Bearer %s"
values: [$__githubAccessToken]
)
@remove
# Create the authorization header to send to GitHub
githubRequestHeaders: _echo(
value: [
{ name: "Accept", value: "application/vnd.github+json" }
{ name: "Authorization", value: $__authorizationHeader }
]
)
@remove
@export(as: "githubRequestHeaders")
githubAPIEndpoint: _sprintf(
string: "https://api.github.com/repos/%s/%s/actions/artifacts?per_page=%s&name=%s"
values: [$repoOwner, $repoProject, $perPage, $artifactName]
)
# Use the field from "Send HTTP Request Fields" to connect to GitHub
gitHubArtifactData: _sendJSONObjectItemHTTPRequest(
input: {
url: $__githubAPIEndpoint
options: { headers: $__githubRequestHeaders }
}
)
@remove
# Finally just extract the URL from within each "artifacts" item
gitHubProxyArtifactDownloadURLs: _objectProperty(
object: $__gitHubArtifactData
by: { key: "artifacts" }
)
@underEachArrayItem(passValueOnwardsAs: "artifactItem")
@applyField(
name: "_objectProperty"
arguments: { object: $artifactItem, by: { key: "archive_download_url" } }
setResultInResponse: true
)
@export(as: "gitHubProxyArtifactDownloadURLs")
}
query CreateHTTPRequestInputs
@depends(on: "RetrieveProxyArtifactDownloadURLs")
{
httpRequestInputs: _echo(value: $gitHubProxyArtifactDownloadURLs)
@underEachArrayItem(passValueOnwardsAs: "url")
@applyField(
name: "_objectAddEntry"
arguments: {
object: {
options: { headers: $githubRequestHeaders, allowRedirects: null }
}
key: "url"
value: $url
}
setResultInResponse: true
)
@export(as: "httpRequestInputs")
@remove
}
query RetrieveActualArtifactDownloadURLs
@depends(on: "CreateHTTPRequestInputs")
{
_sendHTTPRequests(inputs: $httpRequestInputs) {
artifactDownloadURL: header(name: "Location")
@export(as: "artifactDownloadURLs", type: LIST)
}
}
query PrintSpaceSeparatedArtifactDownloadURLs
@depends(on: "RetrieveActualArtifactDownloadURLs")
{
spaceSeparatedArtifactDownloadURLs: _arrayJoin(
array: $artifactDownloadURLs
separator: " "
)
}Die PHP-Logik lädt den Code direkt aus dem Gato GraphQL-Plugin und aus dem „Power Extensions"-Bundle (benötigt zum Senden von HTTP-Anfragen und anderen Funktionalitäten).
Als eigenständige PHP-App müssen wir explizit angeben, welche Module initialisiert werden, und eine von der Standardkonfiguration abweichende Konfiguration bereitstellen.
Beispielsweise weisen wir das Modul SendHTTPRequests an, die Verbindung zu https://api.github.com/repos zu erlauben, und das Modul EnvironmentFields, den Zugriff auf die Umgebungsvariable GITHUB_ACCESS_TOKEN zu erlauben.
Beachte, dass das GraphQL-Schema beim ersten Ausführen der GraphQL-query generiert und auf der Festplatte zwischengespeichert wird. Auf diese Weise wird ab dem 2. Mal kein Code zur Berechnung des Schemas mehr ausgeführt, was die Ausführung schneller macht.
Schließlich initialisiert die eigenständige App den GraphQL-Server, führt die query dagegen aus und gibt die Antwort aus.
<?php
// File retrieve-github-artifacts.php
declare(strict_types=1);
use GraphQLByPoP\GraphQLServer\Server\StandaloneGraphQLServer;
use PoP\Root\Container\ContainerCacheConfiguration;
// Lade den GraphQL-Server über die eigenständigen PHP-Komponenten
require_once (__DIR__ . '/wordpress/wp-content/plugins/gatographql/vendor/scoper-autoload.php');
// Lade die PRO-Erweiterungen über die eigenständigen PHP-Komponenten
require_once (__DIR__ . '/wordpress/wp-content/plugins/gatographql-power-extensions-bundle/vendor/scoper-autoload.php');
// In der GraphQL-query benötigte Module
$moduleClasses = [
\PoPSchema\EnvironmentFields\Module::class,
\PoPSchema\FunctionFields\Module::class,
\GraphQLByPoP\ExportDirective\Module::class,
\GraphQLByPoP\DependsOnOperationsDirective\Module::class,
\GraphQLByPoP\RemoveDirective\Module::class,
\PoPSchema\ApplyFieldDirective\Module::class,
\PoPSchema\SendHTTPRequests\Module::class,
\PoPSchema\ConditionalMetaDirectives\Module::class,
\PoPSchema\DataIterationMetaDirectives\Module::class,
];
// Konfiguriere die Module
$moduleClassConfiguration = [
\PoP\GraphQLParser\Module::class => [
\PoP\GraphQLParser\Environment::ENABLE_MULTIPLE_QUERY_EXECUTION => true,
\PoP\GraphQLParser\Environment::USE_LAST_OPERATION_IN_DOCUMENT_FOR_MULTIPLE_QUERY_EXECUTION_WHEN_OPERATION_NAME_NOT_PROVIDED => true,
\PoP\GraphQLParser\Environment::ENABLE_RESOLVED_FIELD_VARIABLE_REFERENCES => true,
\PoP\GraphQLParser\Environment::ENABLE_COMPOSABLE_DIRECTIVES => true,
],
\PoPSchema\SendHTTPRequests\Module::class => [
\PoPSchema\SendHTTPRequests\Environment::SEND_HTTP_REQUEST_URL_ENTRIES => [
'#https://api.github.com/repos/(.*)#',
],
],
\PoPSchema\EnvironmentFields\Module::class => [
\PoPSchema\EnvironmentFields\Environment::ENVIRONMENT_VARIABLE_OR_PHP_CONSTANT_ENTRIES => [
'GITHUB_ACCESS_TOKEN',
],
],
];
// Schema auf der Festplatte zwischenspeichern, um die Ausführung ab dem 2. Mal zu beschleunigen
$containerCacheConfiguration = new ContainerCacheConfiguration('MyGraphQLServer', true, 'retrieve-github-artifacts', __DIR__ . '/tmp');
// Server initialisieren
$graphQLServer = new StandaloneGraphQLServer($moduleClasses, $moduleClassConfiguration, [], [], $containerCacheConfiguration);
/**
* Auszuführende GraphQL-query, in einer eigenen .gql-Datei gespeichert
*
* @var string
*/
$query = file_get_contents(__DIR__ . '/retrieve-github-artifacts.gql');
// GraphQL-Variablen
$variables = [
'repoOwner' => 'GatoGraphQL',
'repoProject' => 'GatoGraphQL',
'perPage' => 3
];
// Query ausführen
$response = $graphQLServer->execute(
$query,
$variables,
);
// Antwort ausgeben
echo $response->getContent();Um die GraphQL-query auszuführen, starten wir im Terminal (mit jq zum lesbaren Ausgeben des JSON):
php retrieve-github-artifacts.php | jqSchließlich führen wir folgendes aus, um die Artefakt-URLs aus der GraphQL-Antwort zu extrahieren und in WP-CLI zu injizieren:
GITHUB_ARTIFACT_URLS=$(php retrieve-github-artifacts.php \
| grep -E -o '"spaceSeparatedArtifactDownloadURLs\":"(.*)"' \
| cut -d':' -f2- | cut -d'"' -f2- | rev | cut -d'"' -f2- | rev \
| sed 's/\\\//\//g')
wp plugin install ${GITHUB_ARTIFACT_URLS} --force --activate