Filter und Sortierung in der GraphQL-Query anbieten
Filter und Sortierung in der GraphQL-Query anbieten
~8 Min. Lesezeit Zuletzt aktualisiert am 9. August 2026
Die events-Query aus Kapitel 13 liefert bisher immer alle aktiven Veranstaltungen in Einfügereihenfolge. Dieses Kapitel ergänzt einen filter- und einen sort-Parameter, beide als eigene Input-Typen (Kapitel 6), die bewusst die vorhandenen Core-Bausteine FilterTypeInput und SortEnum wiederverwenden.
Den Filter-Input-Typ deklarieren
input EventFilterInput @doc(description: "Identifies which fields to filter events by") {
title: FilterTypeInput
location: FilterTypeInput
}
input EventSortInput @doc(description: "Specifies which fields to sort events by") {
title: SortEnum
start_at: SortEnum
}FilterTypeInput ist derselbe Core-Typ, der bereits in Kapitel 3 in der Produktsuche aufgetaucht ist - er bringt Operatoren wie eq, like, in mit, ohne dass das Event-Modul sie neu definieren muss. SortEnum ist ein einfaches Enum mit den Werten ASC und DESC, ebenfalls aus Magento_CatalogGraphQl.
Die Argumente an der Query ergänzen
type Query {
events(
filter: EventFilterInput
sort: EventSortInput
pageSize: Int = 20
currentPage: Int = 1
): Events
@resolver(class: "Mironsoft\\Event\\Model\\Resolver\\Events")
@doc(description: "Returns a filtered, sorted, paginated list of active events")
}Den DataProvider erweitern
Die getList()-Signatur aus Kapitel 13 bekommt zwei zusätzliche, optionale Parameter. Beide werden über den bereits vorhandenen SearchCriteriaBuilder in Filter bzw. Sortierreihenfolgen übersetzt:
/**
* Fetches active events for the given page, optionally filtered and sorted.
*
* @param int $pageSize Number of events per page
* @param int $currentPage Requested page, 1-based
* @param array<string, array<string, string>>|null $filter Field => [operator => value]
* @param array<string, string>|null $sort Field => direction (ASC/DESC)
* @return array{items: array<int, array<string, mixed>>, total_count: int, page_info: array<string, int>}
*/
public function getList(
int $pageSize,
int $currentPage,
?array $filter = null,
?array $sort = null
): array {
$this->searchCriteriaBuilder->addFilter(EventInterface::IS_ACTIVE, 1);
foreach ($filter ?? [] as $field => $operatorValuePairs) {
foreach ($operatorValuePairs as $operator => $value) {
$this->searchCriteriaBuilder->addFilter($field, $value, $operator);
}
}
$this->searchCriteriaBuilder->setCurrentPage($currentPage);
$this->searchCriteriaBuilder->setPageSize($pageSize);
$searchCriteria = $this->searchCriteriaBuilder->create();
foreach ($sort ?? [] as $field => $direction) {
$sortOrder = $this->sortOrderBuilder->setField($field)
->setDirection($direction)
->create();
$searchCriteria->setSortOrders([$sortOrder]);
}
// ... Rest wie in Kapitel 13: Repository aufrufen, Items mappen, page_info bauen
}$sortOrderBuilder (\Magento\Framework\Api\SortOrderBuilder) kommt als weitere Konstruktor-Abhängigkeit hinzu - konsequent per Constructor Property Promotion, wie jede andere Abhängigkeit in diesem Projekt.
Den Resolver anpassen
$filter = $args['filter'] ?? null;
$sort = $args['sort'] ?? null;
return $this->eventsDataProvider->getList(
(int) ($args['pageSize'] ?? 20),
(int) ($args['currentPage'] ?? 1),
$filter,
$sort
);Die erweiterte Query in der Praxis
query {
events(
filter: { location: { eq: "Berlin" } }
sort: { start_at: ASC }
pageSize: 10
) {
items { title location start_at }
total_count
}
}Achtung: $args['filter'] kommt aus GraphQL als verschachteltes Array mit dem Operator als Schlüssel (['location' => ['eq' => 'Berlin']]) - praktisch identisch mit dem, was addFieldToFilter() selbst als zweiten Parameter erwartet. Diese strukturelle Ähnlichkeit ist kein Zufall: FilterTypeInput wurde bewusst so modelliert, dass es sich direkt in Magentos Collection-Filter-API übersetzen lässt.
Tipp: Bei mehreren gleichzeitig gesetzten Filterfeldern verknüpft SearchCriteriaBuilder::addFilter() ohne weitere Angaben automatisch per UND - für ODER-Verknüpfungen bräuchte es eine gemeinsame Filtergruppe über addFilters() mit mehreren Filtern im selben Array. Für die meisten Storefront-Filter (wie hier) reicht die einfache UND-Verknüpfung völlig aus.
Kapitel 15 rundet Block 4 ab: eine einzelne Veranstaltung gezielt per Identifier abfragen, statt immer die gesamte (gefilterte) Liste zu laden.