Bir API ile Kodlama
Bir API ile KodlamaBlokları sunucu (PHP) ve istemci (JS) tarafında oluşturmak için DRY kod kullanımı

Blokları sunucu (PHP) ve istemci (JS) tarafında oluşturmak için DRY kod kullanımı

Dinamik (Gutenberg) bloklar, blok ön uçta oluşturulduğunda yapılarını ve içeriklerini anında oluşturan bloklardır.

Dinamik bir bloğun ön uçta (WordPress editöründe görüntülemek için) ve sunucu tarafında (blog yazısının HTML'sini oluşturmak için) oluşturulması, genellikle verilerini iki farklı şekilde çeker:

  • İstemci tarafında (JavaScript) API'ye bağlanma
  • Sunucu tarafında (PHP) WordPress fonksiyonlarını çağırma

Gato GraphQL ve uzantıları sayesinde bu mantığı DRY hâle getirmek, yani hem istemci hem de sunucu tarafı için veri çekmeye yönelik tek bir doğruluk kaynağına sahip olmak mümkündür. Bunu nasıl yapacağımızı inceleyelim.

GraphQL queries'i .gql dosyalarında saklamak

İstemciden GraphQL sunucusuna bağlanmak için genellikle GraphQL query'i JavaScript kodunun içine gömerek çalıştırırız:

const response = await fetch(endpoint, {
  body: JSON.stringify({
    query: `
      query {
        posts {
          id
          title
          author {
            id
            name
          }
        }
      }
    `
  )
} );

Alternatif olarak GraphQL query'i bir .gql (veya .graphql) dosyasında saklayabilir ve Webpack'in raw-loader aracını kullanarak içeriğini içe aktarabiliriz:

// File webpack.config.js
const config = require( '@wordpress/scripts/config/webpack.config' );
 
config.module.rules.push(
  {
    test: /\.(gql|graphql)$/i,
    use: 'raw-loader',
  },
);
 
module.exports = config;

(Bu kod Webpack v4 için çalışır; v5 için bunun yerine Asset Modules kullanmamız gerekir.)

Ardından GraphQL query'i bir .gql dosyasının içine yerleştiririz:

# File graphql-documents/fetch-posts-with-author.gql
query {
  posts {
    id
    title
    author {
      id
      name
    }
  }
}

Son olarak bloğun kodu içinde dosyayı içe aktarır ve içeriğini fetch'e aktarırız:

import graphQLQuery from './graphql-documents/fetch-posts-with-author.gql';
 
// ...
 
const response = await fetch(endpoint, {
  body: JSON.stringify({
    query: graphQLQuery
  )
} );

.gql dosyalarını sunucu tarafında çözümlemek

Yukarıda oluşturduğumuz GraphQL dosyası, blok için veri çekmeye yönelik tek doğruluk kaynağımız olacaktır. İstemci tarafı için bu gereksinimi zaten karşılıyor; şimdi bunu sunucu tarafı için de nasıl yapacağımızı görelim.

Internal GraphQL Server uzantısı, PHP kodu kullanarak uygulamamız içinden çağrılabilen bir sunucu kurar.

Internal GraphQL Server, GraphQLServer sınıfı aracılığıyla aşağıdaki statik metodları sağlar:

  • executeQuery: Bir GraphQL query'i çalıştırır
  • executeQueryInFile: Bir (.gql) dosyasında bulunan GraphQL query'i çalıştırır
  • executePersistedQuery: Kalıcı hâle getirilmiş bir GraphQL query'i çalıştırır (ID'sini int olarak veya slug'ını string olarak sağlayarak) (Persisted Queries uzantısı gereklidir)

executeQueryInFile imzası şu şekildedir:

namespace GatoGraphQL\InternalGraphQLServer;
 
class GraphQLServer {
  /**
   * Execute a GraphQL query contained in a (`.gql`) file
   */
  public static function executeQueryInFile(
      string $file,
      array $variables = [],
      ?string $operationName = null
  ): Response {
    // ...
  }
}

Daha önce oluşturulan .gql dosyasını geçirerek executeQueryInFile'ı çağırmak, dinamik bloğu oluştururken verileri almamızı sağlar:

use GatoGraphQL\InternalGraphQLServer\GraphQLServer;
 
$block = [
  'render_callback' => function(array $attributes, string $content): string {
    // Provide the GraphQL query file
    $file = __DIR__ . '/blocks/my-block/graphql-documents/fetch-posts-with-author.gql';
 
    // Execute the query against the internal server
    $response = GraphQLServer::executeQueryInFile($file);
 
    // Get the content and decode it
    $responseContent = json_decode($response->getContent(), true);
 
    // Access the data and errors from the response
    $data = $responseContent["data"] ?? [];
    $errors = $responseContent["errors"] ?? [];
 
    // Do something with the data
    // $content = $this->useGraphQLData($content, $data, $errors);
    // ...
 
    return $content;
  },
];
register_block_type("namespace/my-block", $block);

Bu sayede tek bir .gql dosyası, blokları hem istemci hem de sunucu tarafında beslemek için veri çeker.