GraphQL API ile Etkileşim
GraphQL API ile EtkileşimGato GraphQL'i WordPress Olmadan Çalıştırma

Gato GraphQL'i WordPress Olmadan Çalıştırma

Gato GraphQL, Composer aracılığıyla yönetilen bağımsız PHP bileşenleri kullanılarak inşa edilmiştir; bu sayede GraphQL sunucusunu oluşturan tüm PHP bileşenleri WordPress'e bağımlı değildir!

Dolayısıyla, GraphQL sunucusu bağımsız bir PHP uygulaması olarak çalışabilir ve onu WordPress tabanlı veya başka herhangi bir PHP uygulamasının içine dahil edebilirsiniz.

Herhangi bir kullanım senaryosunda uygulamanızın WordPress verilerine erişmesi gerekmiyorsa, en azından o senaryo için hazır demeksiniz.

Bu video böyle bir kullanım senaryosunu göstermektedir: Geliştirme sürecinde GitHub Actions'tan artifact'ları indirmek/yüklemek için GitHub'ın API'si ile etkileşim kurmak:

Headless WordPress without Wordpress demo: GraphQL query çalıştırma

Videoda, GraphQL query GitHub Actions'ta oluşturulan en son Gato GraphQL eklentilerini almak için bir HTTP isteği çalıştırır; bu eklentiler, bir pull request birleştirildiğinde artifact olarak yüklenir.

GraphQL yanıtındaki artifact'ların URL'leri daha sonra WP-CLI'ye enjekte edilerek eklentilerin testleri çalıştırmak üzere yerel bir DEV web sunucusuna otomatik olarak yüklenmesi sağlanır.

Bu kullanım senaryosunda, hiçbir WordPress verisine erişilmediğinden, GraphQL sunucusu zaten bağımsız bir PHP uygulaması olarak çalışabilir.

Ayrıntılı: Gato GraphQL'i Bağımsız Bir PHP Uygulaması Olarak Çalıştırma

Aşağıda demo videonun ayrıntılı açıklaması yer almaktadır.

Çalıştırılacak GraphQL query'yi retrieve-github-artifacts.gql dosyası altında sağlıyoruz.

Query, GITHUB_ACCESS_TOKEN ortam değişkeninden erişim token'ını alarak GitHub API'sine bağlanır. Sağlanan değişkenlerden actions/artifacts endpoint'inin tam yolunu dinamik olarak oluşturur ve ardından buna karşı bir HTTP isteği gönderir.

Yanıttan, her artifact öğesindeki "download URL"yi çıkarır ve bunlara karşı asenkron HTTP istekleri gönderir. Bu "download URL"lerin her birinin Location başlığından indirilebilir dosyanın gerçek URL'sini elde ederiz.

Son olarak, WP-CLI'ye enjekte etmeyi kolaylaştırmak için tüm URL'leri bir boşlukla ayrılmış şekilde yazdırır.

# File retrieve-github-artifacts.gql
 
query RetrieveProxyArtifactDownloadURLs(
  $repoOwner: String!
  $repoProject: String!
  $perPage: Int = 1
  $artifactName: String = ""
) {
  githubAccessToken: _env(name: "GITHUB_ACCESS_TOKEN")
    @remove
 
  # GitHub'a gönderilecek yetkilendirme başlığını oluştur
  authorizationHeader: _sprintf(
    string: "Bearer %s"
    values: [$__githubAccessToken]
  )
    @remove
 
  # GitHub'a gönderilecek yetkilendirme başlığını oluştur
  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]
  )
 
  # GitHub'a bağlanmak için "Send HTTP Request Fields" alanını kullan
  gitHubArtifactData: _sendJSONObjectItemHTTPRequest(
    input: {
      url: $__githubAPIEndpoint
      options: { headers: $__githubRequestHeaders }
    }
  )
    @remove
 
  # Son olarak her "artifacts" öğesinden URL'yi çıkar
  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: " "
  )
}

PHP mantığı, kodu doğrudan Gato GraphQL eklentisinden ve "Power Extensions" paketinden yükler (HTTP istekleri göndermek ve diğer işlevler için gereklidir).

Bağımsız bir PHP uygulaması olarak, hangi modüllerin başlatıldığını açıkça belirtmeli ve varsayılan olmayan yapılandırmaları sağlamalıyız.

Örneğin, SendHTTPRequests modülüne https://api.github.com/repos adresine bağlanmaya izin vermesini ve EnvironmentFields modülüne GITHUB_ACCESS_TOKEN ortam değişkenine erişmesine izin vermesini bildiririz.

GraphQL şemasının, GraphQL query'si ilk kez çalıştırıldığında oluşturulduğunu ve diske önbelleğe alındığını unutmayın. Bu sayede 2. kez itibaren şemayı hesaplayan kodun hiçbiri çalıştırılmaz, bu da yürütmeyi daha hızlı kılar.

Son olarak, bağımsız uygulama GraphQL sunucusunu başlatır, query'yi buna karşı çalıştırır ve yanıtı yazdırır.

<?php
// File retrieve-github-artifacts.php
 
declare(strict_types=1);
 
use GraphQLByPoP\GraphQLServer\Server\StandaloneGraphQLServer;
use PoP\Root\Container\ContainerCacheConfiguration;
 
// GraphQL sunucusunu bağımsız PHP bileşenleri aracılığıyla yükle
require_once (__DIR__ . '/wordpress/wp-content/plugins/gatographql/vendor/scoper-autoload.php');
 
// PRO uzantılarını bağımsız PHP bileşenleri aracılığıyla yükle
require_once (__DIR__ . '/wordpress/wp-content/plugins/gatographql-power-extensions-bundle/vendor/scoper-autoload.php');
 
// GraphQL query'de gerekli modüller
$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,
];
 
// Modülleri yapılandır
$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',
    ],
  ],
];
 
// 2. kez itibaren yürütmeyi hızlandırmak için şemayı diske önbelleğe al
$containerCacheConfiguration = new ContainerCacheConfiguration('MyGraphQLServer', true, 'retrieve-github-artifacts', __DIR__ . '/tmp');
 
// Sunucuyu başlat
$graphQLServer = new StandaloneGraphQLServer($moduleClasses, $moduleClassConfiguration, [], [], $containerCacheConfiguration);
 
/**
 * Çalıştırılacak GraphQL query, kendi .gql dosyasında saklanır
 *
 * @var string
 */
$query = file_get_contents(__DIR__ . '/retrieve-github-artifacts.gql');
 
// GraphQL değişkenleri
$variables = [
  'repoOwner' => 'GatoGraphQL',
  'repoProject' => 'GatoGraphQL',
  'perPage' => 3
];
 
// Query'yi çalıştır
$response = $graphQLServer->execute(
  $query,
  $variables,
);
 
// Yanıtı yazdır
echo $response->getContent();

GraphQL query'sini çalıştırmak için terminalde şunu çalıştırırız (jq kullanarak JSON çıktısını güzel biçimde yazdırmak için):

php retrieve-github-artifacts.php | jq

Son olarak, artifact URL'lerini GraphQL yanıtından çıkarmak ve WP-CLI'ye enjekte etmek için şunu çalıştırırız:

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