Hyvä GraphQL-Queries im Frontend einbinden und cachen
AI generated
Hyvä
phtml
Hyvä · GraphQL · Magento 2 · Caching
Eigene Hyvä GraphQL-Queries im Frontend einbinden und cachen
von der .graphql-Datei bis zum Cache-Header

Wer in Hyvä-Themes eigene Frontend-Bausteine wie Produktempfehlungen, individuelle Widgets oder Filterlogik baut, kommt an eigenen Hyvä GraphQL-Queries kaum vorbei. Richtig strukturiert, serverseitig vorgeladen und mehrstufig gecacht, liefern sie Daten schnell nach, ohne Full Page Cache und Ladezeiten zu gefährden.

17 Min. Lesezeit GraphQL · Alpine.js · ViewModel · Full Page Cache Magento 2.4.8 · Hyvä Themes

1. Warum eigene GraphQL-Queries in Hyvä-Templates überhaupt nötig sind

Hyvä ersetzt in vielen Standardblöcken das klassische PHP-Datenladen über Repositories durch direkte GraphQL-Aufrufe aus dem Browser, etwa bei der Suche, im Warenkorb oder bei Produktlisten. Sobald ein Projekt aber eigene Frontend-Bausteine braucht, individuelle Produktempfehlungen, ein Widget mit gefilterten Kategorien oder eine Live-Aktualisierung von Lagerbeständen, reicht die reine Block-Injection nicht mehr aus. Genau hier kommen Hyvä GraphQL-Queries ins Spiel: Sie erlauben es, Daten gezielt und asynchron nachzuladen, ohne dass ein vollständiger Seiten-Reload oder ein zusätzlicher PHP-Controller nötig wird.

Der entscheidende Unterschied zu einer klassischen Repository-Injection im Block oder ViewModel liegt darin, dass Hyvä GraphQL-Queries direkt vom Client aus abgefragt werden können, unabhängig vom Seiten-Cache-Status. Das ist besonders wertvoll für Inhalte, die sich häufiger ändern als der Rest der Seite, etwa Lagerbestände, personalisierte Empfehlungen oder Preise mit kundengruppenspezifischen Sonderkonditionen. Wo eine vollständig serverseitige Lösung den Full Page Cache invalidieren müsste, bleibt die Seite mit einer eigenen GraphQL-Query cachefähig, während nur der betroffene Ausschnitt dynamisch bleibt.

Eigene GraphQL-Queries in Hyvä-Templates sind damit kein Selbstzweck, sondern ein Werkzeug für eine gezielte Trennung von statischem und dynamischem Inhalt. Die folgenden Abschnitte zeigen, wie eine solche Query strukturiert, im Template eingebunden, serverseitig vorgeladen und auf mehreren Ebenen gecacht wird, damit aus einem einzelnen Beispiel ein belastbares Pattern für das ganze Projekt wird.

2. Struktur eigener GraphQL-Query-Dateien im Hyvä-Modul

Eine saubere Struktur für Hyvä GraphQL-Queries beginnt mit der physischen Trennung von Query-Definition und Komponente. Statt eine Query als String direkt im JavaScript oder im phtml-Template zu verstecken, legt man sie als eigenständige .graphql-Datei im Modul ab, etwa unter view/frontend/web/graphql/. Das erlaubt Syntax-Highlighting in der IDE, macht Diffs in Code-Reviews lesbar und ermöglicht es, dieselbe Query aus mehreren Komponenten heraus wiederzuverwenden, ohne sie zu duplizieren.

Geladen wird die Query anschließend gegen den /graphql-Endpunkt von Magento, entweder per fetch() direkt aus Alpine.js oder über einen kleinen gemeinsamen JavaScript-Wrapper, der Header, Store-Kontext und Fehlerbehandlung zentral kapselt. Diese Trennung zwischen der reinen Query-Definition und der Komponente, die sie aufruft, ist der Kern eines wartbaren Ansatzes für Hyvä GraphQL-Queries: Ändert sich das Schema, muss nur die .graphql-Datei angepasst werden, nicht jede einzelne Alpine-Komponente, die sie verwendet.

Für größere Projekte lohnt sich zusätzlich eine Konvention für Query-Namen, die Modul und Zweck erkennen lassen, etwa relatedProducts.graphql oder categoryTeaser.graphql. Das erleichtert es Kolleginnen und Kollegen, bestehende Hyvä GraphQL-Queries wiederzufinden, statt versehentlich eine zweite, leicht abweichende Query für denselben Anwendungsfall zu schreiben.

3. Eine konkrete Query schreiben

Ein realistisches Beispiel für Hyvä GraphQL-Queries ist das Nachladen verwandter Produkte inklusive eines eigenen EAV-Attributs und der zugehörigen Kategoriedaten. Die Query fragt gezielt nur die Felder ab, die die Komponente tatsächlich rendert, kein *-Wildcard, keine ungenutzten Unterobjekte. Das reduziert nicht nur die Antwortgröße, sondern auch die Serverlast, weil Magento intern nur die angefragten Resolver ausführt.

Im folgenden Beispiel liefert die Query pro SKU Name, URL, Bild, Preisspanne, ein eigenes Attribut is_handmade sowie die zugeordneten Kategorien mit UID, Name und URL-Pfad. Die Variable $pageSize hat einen Default-Wert, damit der Aufrufer sie bei Bedarf überschreiben kann, ohne dass sie in jeder Komponente explizit gesetzt werden muss.


# Custom Hyvä GraphQL query for a related-products block
# File: view/frontend/web/graphql/relatedProducts.graphql
query RelatedProductsWithCategories($skus: [String!]!, $pageSize: Int = 6) {
  products(filter: { sku: { in: $skus } }, pageSize: $pageSize) {
    items {
      uid
      sku
      name
      url_key
      small_image {
        url
        label
      }
      price_range {
        minimum_price {
          final_price {
            value
            currency
          }
        }
      }
      # Custom EAV attribute exposed via graphql_schema.graphqls
      is_handmade
      categories {
        uid
        name
        url_path
      }
    }
    total_count
  }
}

Diese Query ist bewusst schmal gehalten: Jedes zusätzliche Feld, insbesondere verschachtelte Objekte wie categories, kostet Resolver-Zeit im Backend. Wird sie auf Kategorieseiten oder in der Produktliste mehrfach ausgeführt, summiert sich das schnell zu spürbarer Serverlast, wenn die Feldauswahl zu großzügig ausfällt.

4. Integration im phtml-Template mit Alpine.js

Im Template wird die Query über eine Alpine.js-Komponente eingebunden, die einen fetch()-Wrapper, einen Loading-State und einen Error-State kapselt. Wichtig ist dabei, niemals die doppelte geschweifte Alpine-Mustache-Syntax direkt im Markup zu verwenden, weil Magentos eigener Template-Parser doppelte geschweifte Klammern als Direktive interpretiert. Stattdessen werden Werte konsequent über x-text und x-show gebunden.

Der folgende Ausschnitt zeigt eine vollständige Integration: Die Alpine-Komponente hält items, loading und error als reaktiven State, ruft bei Bedarf refresh() auf und rendert die Produktliste per x-for. Da Hyvä GraphQL-Queries asynchron laufen, muss der Loading-State sichtbar sein, bevor die ersten Daten eintreffen, sonst wirkt die Seite kurzzeitig leer oder fehlerhaft.


<?php
/** @var \Magento\Framework\View\Element\Template $block */
/** @var \Hyva\Theme\Model\ViewModelRegistry $viewModels */
/** @var \Mironsoft\GraphQlWidgets\ViewModel\RelatedProducts $relatedProductsViewModel */
$relatedProductsViewModel = $viewModels->require(\Mironsoft\GraphQlWidgets\ViewModel\RelatedProducts::class);
$hyvaCsp = $viewModels->require(\Hyva\Theme\ViewModel\HyvaCsp::class);
?>
<div
  x-data="relatedProductsGraphql({
    skus: <?= /* @noEscape */ $relatedProductsViewModel->getRelatedSkusJson() ?>,
    initialItems: <?= /* @noEscape */ $relatedProductsViewModel->getInitialItemsJson() ?>
  })"
  class="my-8"
>
  <p class="text-lg font-bold mb-4">Das koennte dir auch gefallen</p>

  <template x-if="loading">
    <p class="text-sm text-slate-500">Lade Empfehlungen ...</p>
  </template>

  <template x-if="error">
    <p class="text-sm text-red-600" x-text="error"></p>
  </template>

  <div class="grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-6 gap-4" x-show="!loading && !error">
    <template x-for="item in items" :key="item.uid">
      <a :href="item.url_key" class="block border border-slate-200 rounded-xl p-3 hover:shadow-md transition-shadow">
        <img :src="item.small_image.url" :alt="item.small_image.label" class="w-full h-auto mb-2" loading="lazy">
        <p class="text-sm font-semibold" x-text="item.name"></p>
        <p class="text-sm text-slate-600" x-text="item.price_range.minimum_price.final_price.value"></p>
      </a>
    </template>
  </div>
</div>

<script>
function relatedProductsGraphql({ skus, initialItems }) {
  return {
    items: initialItems,
    loading: false,
    error: null,
    // Fetch fresh data from the /graphql endpoint on demand
    async refresh() {
      this.loading = true;
      this.error = null;
      try {
        const response = await fetch('/graphql', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json', 'Store': 'default' },
          body: JSON.stringify({
            query: window.relatedProductsQuery,
            variables: { skus, pageSize: 6 }
          })
        });
        const { data, errors } = await response.json();
        if (errors) {
          throw new Error(errors[0].message);
        }
        this.items = data.products.items;
      } catch (e) {
        this.error = 'Empfehlungen konnten nicht geladen werden';
      } finally {
        this.loading = false;
      }
    },
    init() {
      // SSR data is already present, only refresh on an explicit event
      window.addEventListener('wishlist-updated', () => this.refresh());
    }
  };
}
</script>
<?= $hyvaCsp->registerInlineScript() ?>

Diese Struktur trennt sauber zwischen dem, was serverseitig als Startzustand mitgeliefert wird, und dem, was per GraphQL nachgeladen wird. Die Komponente startet nie leer und schickt auch nicht sofort einen Request ab, sondern nutzt initialItems aus dem ViewModel als sofort sichtbaren Zustand.

5. Serverseitiges Vorladen via ViewModel als Hybrid-Ansatz

Ein reiner Client-only-Ansatz für Hyvä GraphQL-Queries hat einen spürbaren Nachteil: Der Nutzer sieht beim ersten Rendern einen Loading-State, bevor überhaupt Daten da sind. Der robustere Hybrid-Ansatz lädt die Startdaten serverseitig über ein ViewModel vor und übergibt sie als JSON an die Alpine-Komponente. GraphQL wird dann nur noch für Aktualisierungen genutzt, etwa nachdem der Nutzer die Wunschliste geändert hat oder eine Filteroption umgeschaltet wurde.

Das folgende ViewModel nutzt Constructor Property Promotion und lädt die initialen Produktdaten über das bestehende Product-Repository, nicht über GraphQL selbst. Damit bleibt der erste Seitenaufruf vollständig serverseitig gerendert und cachefähig, während Hyvä GraphQL-Queries erst beim späteren Nachladen ins Spiel kommen.


<?php

declare(strict_types=1);

namespace Mironsoft\GraphQlWidgets\ViewModel;

use Hyva\Theme\Model\ViewModelInterface;
use Magento\Catalog\Api\ProductRepositoryInterface;
use Magento\Framework\Exception\NoSuchEntityException;
use Magento\Framework\Serialize\Serializer\Json;

/**
 * Hybrid view model: preloads related products server-side for the first
 * render, GraphQL is only used later to refresh the block on the client.
 */
class RelatedProducts implements ViewModelInterface
{
    /**
     * @param ProductRepositoryInterface $productRepository Repository used for the initial SSR load.
     * @param Json $json Serializer used to pass data safely into Alpine.js.
     * @param string[] $relatedSkus SKUs of the related products for the current product.
     */
    public function __construct(
        private readonly ProductRepositoryInterface $productRepository,
        private readonly Json $json,
        private readonly array $relatedSkus = []
    ) {
    }

    /**
     * Returns the SKUs of related products as a JSON string for Alpine.js.
     *
     * @return string
     */
    public function getRelatedSkusJson(): string
    {
        return $this->json->serialize($this->relatedSkus);
    }

    /**
     * Loads the initial related-product items server-side so the block
     * renders immediately without waiting for a client-side GraphQL request.
     *
     * @return string
     * @throws \Magento\Framework\Exception\LocalizedException
     */
    public function getInitialItemsJson(): string
    {
        $items = [];
        foreach ($this->relatedSkus as $sku) {
            try {
                $product = $this->productRepository->get($sku);
                $items[] = [
                    'uid' => (string) $product->getId(),
                    'sku' => $product->getSku(),
                    'name' => $product->getName(),
                    'url_key' => $product->getProductUrl(),
                ];
            } catch (NoSuchEntityException $e) {
                continue;
            }
        }

        return $this->json->serialize($items);
    }
}

Dieser Hybrid-Ansatz kombiniert die Vorteile beider Welten: Das erste Rendern ist vollständig serverseitig und damit vom Full Page Cache erfassbar, während GraphQL die Rolle einer gezielten Nachlade-Schicht übernimmt, die nur bei tatsächlichem Bedarf aktiv wird.

6. Serverseitiges Caching von GraphQL-Antworten

Magentos GraphQL-Endpunkt respektiert dieselbe Cache-Infrastruktur wie der Rest des Shops, sofern die Query keine kundengruppen- oder sitzungsabhängigen Felder enthält. Für cachefähige Hyvä GraphQL-Queries setzt Magento passende Cache-Control- und X-Magento-Tags-Header, die es dem Full Page Cache erlauben, die Antwort zu speichern und bei einer Produktänderung gezielt über die passenden Tags zu invalidieren, statt den gesamten Cache zu leeren.

Für wiederkehrende, immer gleiche Queries lohnt sich zusätzlich der Einsatz von Persisted Queries: Statt den vollständigen Query-String bei jedem Request zu übertragen, wird beim Deployment ein Hash für jede bekannte Query registriert, und der Client sendet nur noch diesen Hash. Das reduziert Payload-Größe und erlaubt es, serverseitig eine Whitelist zulässiger Hyvä GraphQL-Queries zu führen, was gleichzeitig ein Sicherheitsgewinn ist, weil beliebige Ad-hoc-Queries vom Client aus nicht mehr möglich sind.


{
  "version": 1,
  "queries": {
    "a3f8c2e19b7d4f0a2c8e5b6d1f9a0c3e": {
      "operationName": "RelatedProductsWithCategories",
      "query": "query RelatedProductsWithCategories($skus: [String!]!, $pageSize: Int = 6) { products(filter: { sku: { in: $skus } }, pageSize: $pageSize) { items { uid sku name } total_count } }",
      "cacheable": true,
      "ttl": 3600
    }
  }
}

Wichtig für das Zusammenspiel mit dem Full Page Cache: Sobald eine Query personalisierte Felder enthält, etwa kundenspezifische Preise, markiert Magento die Antwort automatisch als nicht cachefähig. Wer Hyvä GraphQL-Queries plant, sollte personalisierte und generische Felder deshalb bewusst in getrennte Queries aufteilen, statt sie in einer einzigen Anfrage zu mischen und damit die gesamte Antwort ungewollt uncacheable zu machen.

7. Clientseitiges Caching im Frontend

Serverseitiges Caching allein verhindert nicht, dass mehrere gleichzeitig auf der Seite eingebundene Komponenten dieselbe Query mehrfach abfeuern, etwa wenn ein Produktkarussell und ein Empfehlungs-Widget zufällig dieselben SKUs anfragen. Ein einfaches, aber wirksames Pattern für Hyvä GraphQL-Queries ist ein zentraler In-Memory-Cache über Alpine.store(), der Ergebnisse anhand eines Cache-Keys aus Query-Name und Variablen ablegt und mit einer TTL versieht.

Fragt eine zweite Komponente dieselbe Query mit denselben Variablen innerhalb der TTL erneut an, wird das Ergebnis direkt aus dem Store bedient, ohne einen weiteren Netzwerk-Request auszulösen. Läuft bereits ein Request für denselben Key, kann die zweite Komponente auf dessen Promise warten, statt einen zweiten identischen Request zu starten. Das reduziert die Anzahl paralleler GraphQL-Requests bei Seiten mit mehreren gleichartigen Widgets spürbar und entlastet sowohl das Backend als auch die Netzwerkverbindung des Nutzers.

Ein TTL von wenigen Sekunden bis wenigen Minuten reicht in der Praxis für die meisten Anwendungsfälle aus, da echte Preis- oder Lageränderungen selten so kurzfristig relevant sind, dass ein Sekundenbruchteil Verzögerung ein Problem darstellt. Für tatsächlich zeitkritische Daten, etwa den letzten verfügbaren Lagerbestand kurz vor Checkout, sollte der Cache gezielt umgangen oder die TTL auf null gesetzt werden.

8. Performance-Optimierung

Die wichtigste Stellschraube bei Hyvä GraphQL-Queries ist die Feldselektion: Jedes zusätzlich angefragte Feld kostet Resolver-Zeit im Backend und Bytes in der Antwort. Statt ein vollständiges Produktobjekt mit allen verfügbaren Feldern abzufragen, sollte jede Komponente nur exakt die Felder anfordern, die sie tatsächlich rendert. Das gilt besonders für verschachtelte Relationen wie categories oder configurable_options, die intern zusätzliche Resolver-Aufrufe auslösen können.

Ein zweites, oft übersehenes Problem ist N+1 bei verschachtelten Feldern: Wird für jedes Element einer Liste eine eigene Unter-Query mit eigenem Resolver-Aufruf ausgelöst, summiert sich das bei größeren Listen zu spürbarer Latenz. Magentos GraphQL-Resolver sind für Batch-Auflösung ausgelegt, sofern die Query so geschrieben wird, dass verwandte Daten in einem Rutsch mitgeladen werden, statt sie über mehrere Rundreisen aufzulösen.

Da der native Magento-GraphQL-Endpunkt kein HTTP-Batching mehrerer unabhängiger Operationen unterstützt, lassen sich mehrere logische Hyvä GraphQL-Queries über GraphQL-Aliase in einer einzigen Anfrage bündeln. Das folgende Beispiel lädt Kategorie-Teaser und Produktvorschläge in einem Request, statt zwei separate HTTP-Requests abzusetzen:


# Batching two logically separate Hyvä GraphQL queries via aliases
# in a single HTTP round trip
query BatchedHomeWidgets($categoryId: String!, $skus: [String!]!) {
  categoryTeaser: categories(filters: { category_uid: { eq: $categoryId } }) {
    items {
      uid
      name
      image
    }
  }
  relatedTeaser: products(filter: { sku: { in: $skus } }, pageSize: 4) {
    items {
      uid
      name
      small_image {
        url
      }
    }
  }
}

Diese Batching-Technik spart einen kompletten HTTP-Roundtrip und senkt damit die wahrgenommene Ladezeit spürbar, besonders auf mobilen Verbindungen mit höherer Latenz. Kombiniert mit minimaler Feldselektion und einem clientseitigen Cache ergibt sich ein Satz an eigenen Queries, der Backend und Netzwerk gleichermaßen schont.

9. Sicherheit bei eigenen GraphQL-Queries

Ein offener /graphql-Endpunkt ohne Schutzmaßnahmen ist ein attraktives Ziel für Query-basierte Denial-of-Service-Angriffe: Eine tief verschachtelte Query mit vielen Wiederholungen kann das Backend erheblich stärker belasten als ein einzelner REST-Request. Magento bietet dafür Query-Complexity-Limits und Depth-Limiting, die konfiguriert werden sollten, bevor eigene Hyvä GraphQL-Queries in Produktion gehen, insbesondere wenn Nutzer Variablen wie Filterwerte oder Pagination-Größen selbst beeinflussen können.

Introspection, also die Möglichkeit, das komplette Schema per Query abzufragen, sollte in Produktionsumgebungen deaktiviert werden. Sie ist während der Entwicklung nützlich, gibt in der Produktion aber unnötig Details über interne Strukturen preis, die Angreifern das Auffinden schwach geschützter Felder erleichtern. Zusätzlich sollten ACL-geschützte Felder, etwa interne Kalkulationsdaten oder B2B-spezifische Preisinformationen, konsequent über Magentos Resolver-Berechtigungen abgesichert werden, statt sich allein auf die Frontend-Logik zu verlassen.

Rate-Limiting auf Ebene des Webservers oder eines vorgeschalteten Reverse-Proxys ergänzt diese Maßnahmen, indem es die Anzahl der Requests pro IP oder Session begrenzt. Für Hyvä GraphQL-Queries, die per Persisted Queries whitelisted sind, lässt sich Rate-Limiting sogar granular pro Query-Hash konfigurieren, was gezielter ist als ein pauschales Limit über den gesamten Endpunkt.

Aufgabe Unsicher / Ineffizient Empfohlenes Pattern Vorteil
Introspection In Produktion aktiviert lassen Deaktivieren via graphql.xml Verhindert Schema-Fingerprinting
Feldselektion Vollständiges Objekt laden Nur benötigte Felder anfragen Kleinere Payloads, weniger Serverlast
Mehrfache Requests Jede Komponente lädt eigenständig Alpine.store() als In-Memory-Cache Keine doppelten Requests
Verschachtelte Relationen Einzelabfrage pro Kind-Element (N+1) Batch-Query mit Alias in einem Request Ein Roundtrip statt N
Cache-Invalidierung Keine Cache-Tags gesetzt X-Magento-Tags respektieren FPC-kompatibel, gezielte Invalidierung
Query-Floods Kein Schutz gegen tiefe Verschachtelung Complexity- und Depth-Limits Schützt vor Denial-of-Service

Mironsoft

Hyvä-Frontend-Entwicklung, GraphQL-Architektur und Caching für Magento 2

Eigene GraphQL-Queries, die den Full Page Cache nicht ausbremsen?

Wir konzipieren und implementieren eigene Hyvä GraphQL-Queries für individuelle Frontend-Bausteine, mit sauberer Feldselektion, ViewModel-Hybrid-Ansatz und mehrstufigem Caching, das serverseitig und clientseitig zusammenspielt.

GraphQL-Architektur-Review

Analyse bestehender Queries auf Feldselektion, N+1-Probleme und Sicherheitslücken

Hyvä-Frontend-Entwicklung

Alpine.js-Komponenten und ViewModel-Hybrid-Ansätze für eigene Widgets

Performance & Caching-Audit

Server- und clientseitige Caching-Strategien im Zusammenspiel mit dem Full Page Cache

10. Zusammenfassung

Eigene Hyvä GraphQL-Queries lösen ein konkretes Problem: Sie erlauben es, dynamische Inhalte gezielt nachzuladen, ohne den Full Page Cache für die restliche Seite zu opfern. Der Weg dorthin führt über eine saubere Trennung von Query-Datei und Komponente, eine bewusst schmale Feldselektion und einen Hybrid-Ansatz, der die ersten Daten serverseitig per ViewModel vorlädt, während GraphQL nur für spätere Aktualisierungen zuständig ist.

Caching entscheidet dabei über Erfolg oder Misserfolg des ganzen Ansatzes: Serverseitig über Cache-Tags und Persisted Queries, clientseitig über einen einfachen Alpine.store()-basierten In-Memory-Cache mit TTL, der doppelte Requests bei mehreren gleichzeitigen Komponenten vermeidet. Ergänzt um Query-Complexity-Limits, deaktivierte Introspection in Produktion und ACL-geschützte Felder entsteht ein Ergebnis, das performant, wartbar und abgesichert ist.

Wer diese Bausteine von Anfang an konsequent anwendet, statt sie nachträglich zu reparieren, spart sich spätere Refactorings unter Zeitdruck. Ein sauber strukturiertes Set an Hyvä GraphQL-Queries lässt sich zudem leicht auf weitere Widgets im selben Projekt übertragen, weil Struktur, Caching-Pattern und Sicherheitsmaßnahmen bereits etabliert sind.

Hyvä GraphQL-Queries im Frontend: Das Wichtigste auf einen Blick

Struktur

Queries als eigene .graphql-Dateien im Modul, getrennt von der Alpine.js-Komponente, die sie aufruft.

Hybrid-Ansatz

ViewModel lädt die Startdaten serverseitig vor, GraphQL übernimmt nur das spätere Nachladen und Aktualisieren.

Caching

Serverseitig über Cache-Tags und Persisted Queries, clientseitig über Alpine.store() mit TTL.

Sicherheit & Performance

Minimale Feldselektion, Batching per Alias, Complexity-Limits und deaktivierte Introspection in Produktion.

11. FAQ: Hyvä GraphQL-Queries im Frontend

1Wann braucht man eigene Hyvä GraphQL-Queries?
Sobald individuelle Widgets oder häufig wechselnde Inhalte außerhalb des Full Page Cache gehalten werden sollen, ohne die restliche Seite uncacheable zu machen.
2Wo legt man Query-Dateien im Modul ab?
Als eigenständige .graphql-Dateien unter view/frontend/web/graphql/, getrennt von der aufrufenden Komponente.
3Wie stört Alpine.js Magentos Parser nicht?
Niemals doppelte geschweifte Mustache-Klammern im Markup verwenden, immer x-text und x-show für dynamische Werte einsetzen.
4Vorteil des ViewModel-Hybrid-Ansatzes?
Startdaten kommen serverseitig, die Komponente startet nie leer. GraphQL übernimmt nur spätere Aktualisierungen.
5Kompatibilität mit dem Full Page Cache?
Personalisierte und generische Felder in getrennte Queries aufteilen, nur generische Queries bleiben cachefähig.
6Was sind Persisted Queries?
Registrierter Hash statt vollständigem Query-String, reduziert Payload und erlaubt eine Whitelist zulässiger Queries.
7Doppelte Requests bei mehreren Komponenten vermeiden?
Zentraler In-Memory-Cache über Alpine.store() mit TTL, laufende Requests werden über deren Promise geteilt.
8N+1-Probleme vermeiden?
Verwandte Daten in einem Rutsch mitladen statt pro Listenelement eine eigene Unter-Query auszulösen.
9Warum Introspection in Produktion deaktivieren?
Sie gibt das komplette Schema preis und erleichtert Angreifern das Auffinden schwach geschützter Felder.
10Schutz vor Query-basierten DoS-Angriffen?
Query-Complexity-Limits und Depth-Limiting in Magento, kombiniert mit Rate-Limiting pro Persisted-Query-Hash.