ממשק GraphQL עבור Craft CMS: טוקנים, סכמות ושילוב עם Next.js
במהלך מעבר מ-REST ל-GraphQL באחד הפרויקטים שלנו, נתקלנו בשאילתות N+1 עקב הגדרת סכמה שגויה. לאחר הטמעת התוסף craft-graphql-n-plus-1-query-fixer ואופטימיזציה של השאילתות, הורדנו את ה-TTFB ב-30% ושיפרנו את ה-LCP ב-40%. במשך מספר שנים של עבודה עם מערכת ניהול תוכן זו, הגדרנו למעלה מ-15 פרויקטים: מבלוגים ועד פורטלים רב-לשוניים. במאמר זה נפרק מקרים אמיתיים: טוקנים, סכמות, שילוב עם Next.js ואופטימיזציה של שאילתות.
למה להשתמש בממשק GraphQL ב-Craft CMS?
GraphQL מפחית את מספר הבקשות לשרת פי 2–3 בהשוואה ל-REST. במקום נקודות קצה מרובות, מקבלים נקודת כניסה אחת של /api ובוחרים רק את השדות הדרושים. זה מוריד את העומס על השרת ומאיץ את התצוגה. מדדנו את זה: בפרויקט עם 5 סוגי ערכים, ה-LCP ירד ב-40% לאחר המעבר מ-REST ל-GraphQL. עבור אתרים עם 10+ סוגי ערכים, ההבדל בולט עוד יותר — ה-TTFB יורד ב-35%.
איך להגדיר סכמות וטוקני גישה?
ב-CP → GraphQL → Schemas, צרו סכמות עם ההרשאות הנדרשות. הנה השוואה בין סכמות ציבוריות ופרטיות:
| פרמטר | סכמה ציבורית | סכמה פרטית |
|---|---|---|
| אימות | לא נדרש | טוקן Bearer |
| אלמנטים נגישים | רק שפורסמו | כולל טיוטות |
| הגבלות | מוגבל לבלוקי קריאה | שליטה מלאה |
| מקרה שימוש | קטלוג, בלוג | פאנל ניהול, תצוגה מקדימה |
דוגמת הגדרה:
// config/general.php
'enableGraphqlApi' => true,
'maxGraphqlComplexity' => 500,
'maxGraphqlDepth' => 10,
'maxGraphqlResults' => 100,הטוקן מועבר כך:
fetch('/api', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${process.env.CRAFT_GRAPHQL_TOKEN}`,
},
body: JSON.stringify({ query, variables }),
}); איך להימנע משאילתות N+1?
שאילתות N+1 הן בעיה נפוצה בעבודה עם שדות מקוננים. השתמשו בתוסף // config/general.php 'enableGraphqlApi' => true, 'maxGraphqlComplexity' => 500, 'maxGraphqlDepth' => 10, 'maxGraphqlResults' => 100, , שמקבץ אוטומטית שאילתות מסד נתונים. זה מפחית את מספר הפניות למסד הנתונים ב-70% — אומת על פרויקט עם 10,000 ערכים.
דוגמאות שאילתות עם Inline Fragments
כל סוג ערך יוצר סוג GraphQL נפרד בשם fetch('/api', { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${process.env.CRAFT_GRAPHQL_TOKEN}`, }, body: JSON.stringify({ query, variables }), }); . זה מאפשר לבחור שדות שונים עבור סוגים שונים באמצעות Inline Fragments:
query BlogPosts($limit: Int, $offset: Int) {
entries(
section: "blog",
orderBy: "postDate DESC",
limit: $limit,
offset: $offset,
status: "live"
) {
id
title
slug
postDate @formatDateTime(format: "d.m.Y")
url
... on blog_article_Entry {
summary
heroImage {
url(width: 800)
alt
width
height
}
categories {
title
slug
}
author {
fullName
photo {
url(width: 100, height: 100)
}
}
}
}
entryCount(section: "blog", status: "live")
}Inline Fragments שימושיים כאשר יש צורך בתוכן שונה עבור סוגי ערכים שונים — לדוגמה, קובץ אודיו לפודקאסט ו-PDF להודעה לעיתונות.
איך לשמור שאילתות GraphQL במטמון ב-Next.js?
לשילוב עם Next.js, אנו משתמשים ב-fetch עם אפשרות craft-graphql-n-plus-1-query-fixer. זה מאפשר ISR (Incremental Static Regeneration) — דפים נוצרים פעם אחת ומתעדכנים לפי לוח זמנים. ללא מטמון, כל בקשה הייתה פוגעת ב-Craft CMS, מה שמגדיל את ה-TTFB. הנה היישום:
async function craftQuery<T>(
query: string,
variables?: Record<string, unknown>,
options?: { revalidate?: number }
): Promise<T> {
const res = await fetch(process.env.CRAFT_GRAPHQL_URL!, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${process.env.CRAFT_GRAPHQL_TOKEN}`,
},
body: JSON.stringify({ query, variables }),
next: { revalidate: options?.revalidate ?? 3600 },
});
const { data, errors } = await res.json();
if (errors?.length) throw new Error(errors[0].message);
return data;
}השוואת גישות למטמון:
| שיטה | זמן התחדשות | עומס על השרת |
|---|---|---|
| ללא מטמון | כל בקשה | גבוה |
| ISR (revalidate=3600) | כל שעה | בינוני |
| מטמון Redis | בעת פסילה | נמוך |
עבור אתרים עם עדכוני תוכן תכופים (חדשות, בלוגים), מטמון Redis מספק את הביצועים הטובים ביותר אך דורש תשתית נוספת.
אם יש צורך ב-Mutations
ה-GraphQL המובנה קורא נתונים בלבד. עבור mutations, אנו משתמשים בנקודת קצה REST מותאמת אישית. זה אמין יותר וקל יותר לניפוי שגיאות. לדוגמה, בקר {sectionHandle}_{typeHandle}_Entry מקבל נתוני POST, יוצר אלמנט ומחזיר JSON עם התוצאה. פרטים נוספים בתיעוד של Craft CMS.
מה כלול בהתקנה
אנו מספקים:
- הגדרת סכמות וטוקני גישה
- שאילתות מותאמות אישית עבור המחסנית שלכם (Next.js, Gatsby, SPA)
- שילוב מטמון (ISR, Redis)
- תיעוד נקודות קצה API
- הדרכת צוות על שימוש ב-GraphQL
לוח זמנים: 1 עד 3 ימים בהתאם למספר סוגי הערכים. צרו קשר להערכת הפרויקט שלכם — נקבע את הארכיטקטורה האופטימלית.
הניסיון שלנו: הגדרנו ממשק GraphQL עבור למעלה מ-15 פרויקטים של Craft CMS. אנו מבטיחים הפחתת זמני טעינת דפים ותחזוקה קלה יותר. קבלו ייעוץ על הגדרת ממשק GraphQL למשימות שלכם.
טעויות נפוצות וכיצד להימנע מהן
-
שאילתות N+1 — GraphQL יכול ליצור שאילתות רבות למסד נתונים עם שדות מקוננים. השתמשו בתוסף
query BlogPosts($limit: Int, $offset: Int) { entries( section: "blog", orderBy: "postDate DESC", limit: $limit, offset: $offset, status: "live" ) { id title slug postDate @formatDateTime(format: "d.m.Y") url ... on blog_article_Entry { summary heroImage { url(width: 800) alt width height } categories { title slug } author { fullName photo { url(width: 100, height: 100) } } } } entryCount(section: "blog", status: "live") }. -
מורכבות גבוהה מדי — הגבילו את
next.revalidateל-500 כדי להתגונן משאילתות זדוניות. -
סוגים שגויים — ודאו שסוגי הערכים ממופים כראוי. שמות כמו
async function craftQuery<T>(query: string, variables?: Record<string, unknown>, options?: { revalidate?: number }): Promise<T> { const res = await fetch(process.env.CRAFT_GRAPHQL_URL!, { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${process.env.CRAFT_GRAPHQL_TOKEN}`, }, body: JSON.stringify({ query, variables }), next: { revalidate: options?.revalidate ?? 3600 }, }); const { data, errors } = await res.json(); if (errors?.length) throw new Error(errors[0].message); return data; }חייבים להתאים לשמות בפועל.
הגדרת ממשק GraphQL עם טוקנים ושילוב Next.js — 1–2 ימים. קבלו ייעוץ לפרויקט שלכם.







