← جميع المقالات >
magento 2magento developmentphpe-commerceadobe-commercetutorialmodule-development

Magento 2 GraphQL API : دليل المطور الشامل (2026)

Share: LinkedIn X Facebook

تعد GraphQL API لماجنتو 2 العمود الفقري لواجهات المتاجر headless الحديثة وتطبيقات PWA وتطبيقات الهاتف المحمول. على عكس REST — التي تتطلب غالبًا جولات متعددة — تسمح GraphQL للعميل بطلب الحقول التي يحتاجها بالضبط في استدعاء واحد. يغطي هذا الدليل المخطط المضمن، المصادقة، طفرات سلة التسوق والدفع، تطوير المحللات المخصصة، وأنماط الأداء المهمة في الإنتاج.

باختصار: يعرض GraphQL في ماجنتو 2 المنتجات والفئات وسلة التسوق والدفع وبيانات العملاء من خلال مخطط typed في /graphql. استخدم queries للقراءة، mutations للكتابة، ووسّع المخطط بمحللات مخصصة عندما لا تكفي الحقول المضمنة.

جدول المحتويات

  1. لماذا GraphQL لماجنتو 2؟
  2. نقطة النهاية والرؤوس وأول استعلام
  3. المخطط الأساسي: المنتجات والفئات والبحث
  4. طفرات سلة التسوق والدفع
  5. مصادقة العميل
  6. بناء محلل استعلام مخصص
  7. بناء طفرة مخصصة
  8. الأداء والتخزين المؤقت
  9. GraphQL مقابل REST: متى تستخدم ماذا
  10. الأسئلة الشائعة التقنية

لماذا GraphQL لماجنتو 2؟

استثمرت Adobe بكثافة في GraphQL كـ API الأساسي للعمليات الموجهة لواجهة المتجر. تظل REST متاحة لتكاملات Admin والأنظمة القديمة، لكن الأعمال الجديدة على الواجهة الأمامية — Hyvä React Checkout و PWA Studio وواجهات Next.js المخصصة — تعمل على GraphQL.

الميزةالتفاصيل
طلب واحداحصل على اسم المنتج وسعره وصورته ومخزونه في استدعاء واحد
لا استرجاع زائديختار العميل فقط الحقول التي يعرضها
مخطط typedتوثيق ذاتي عبر introspection
حالة السلةنموذج token cart_id يناسب الواجهات الأمامية عديمة الحالة
استقرار الإصداراتيتطور المخطط مع إهمال متوافق مع الإصدارات السابقة

نقطة النهاية:

POST https://your-store.com/graphql
Content-Type: application/json

نقطة النهاية والرؤوس وأول استعلام

استعلام منتج أساسي

{
  products(filter: { sku: { eq: "24-MB01" } }) {
    items {
      sku
      name
      price_range {
        minimum_price {
          regular_price {
            value
            currency
          }
        }
      }
      image {
        url
        label
      }
    }
  }
}

أرسله باستخدام curl:

curl -X POST https://your-store.com/graphql \
  -H "Content-Type: application/json" \
  -d '{"query": "{ products(filter: { sku: { eq: \"24-MB01\" } }) { items { sku name } } }"}'

رأس Store (إعدادات المتاجر المتعددة)

عند تشغيل عدة طرق عرض للمتجر، مرر رأس Store:

-H "Store: default"
"

بدونه، قد يعيد ماجنتو بيانات من طريقة عرض المتجر الخاطئة — أسعار خاطئة، لغة خاطئة، عملة خاطئة.

---

## المخطط الأساسي: المنتجات والفئات والبحث

**قائمة الفئات مع الفلاتر**

```graphql
{
  categoryList(filters: { url_key: { eq: "gear" } }) {
    id
    name
    products(pageSize: 12, currentPage: 1) {
      total_count
      items {
        sku
        name
        small_image { url }
        price_range {
          minimum_price {
            final_price { value currency }
          }
        }
      }
      page_info {
        current_page
        total_pages
      }
    }
  }
}

البحث بالنص الكامل

{
  products(search: "backpack", pageSize: 10) {
    total_count
    items {
      sku
      name
      url_key
    }
  }
}
"

يعتمد البحث على مفهرس `catalogsearch_fulltext` و Elasticsearch/OpenSearch. إذا أرجع البحث نتائج فارغة، أعد الفهرسة أولاً:

```bash
bin/magento indexer:reindex catalogsearch_fulltext

خيارات المنتج القابل للتكوين

{
  products(filter: { sku: { eq: "MH01" } }) {
    items {
      sku
      name
      ... on ConfigurableProduct {
        configurable_options {
          attribute_code
          label
          values {
            value_index
            label
          }
        }
        variants {
          product {
            sku
            name
            price_range {
              minimum_price {
                final_price { value }
              }
            }
          }
        }
      }
    }
  }
}

استخدم الأجزاء المضمنة (... on ConfigurableProduct) للوصول إلى الحقول الخاصة بالنوع — وهو نمط GraphQL أساسي في ماجنتو.


طفرات سلة التسوق والدفع

تستخدم سلال الضيوف cart_id (معرف عرض سعر مقنّع). سلال العملاء تستخدم token العميل الموثق.

إنشاء سلة ضيف

mutation {
  createEmptyCart
}

الاستجابة:

{ "data": { "createEmptyCart": "abc123xyz" } }

إضافة منتج إلى السلة

mutation {
  addProductsToCart(
    cartId: "abc123xyz"
    cartItems: [{ sku: "24-MB01", quantity: 1 }]
  ) {
    cart {
      items {
        quantity
        product {
          name
          sku
        }
      }
      prices {
        grand_total {
          value
          currency
        }
      }
    }
  }
}

دمج سلة الضيف بعد تسجيل الدخول

mutation {
  mergeCarts(
    source_cart_id: "abc123xyz"
    destination_cart_id: "customer-cart-id"
  ) {
    items { quantity product { sku } }
  }
}

تعيين عنوان الشحن وطريقة الشحن

mutation {
  setShippingAddressesOnCart(
    input: {
      cart_id: "abc123xyz"
      shipping_addresses: [{
        address: {
          firstname: "John"
          lastname: "Doe"
          street: ["123 Main St"]
          city: "Paris"
          postcode: "75001"
          country_code: FR
          telephone: "0600000000"
        }
      }]
    }
  ) {
    cart {
      shipping_addresses {
        available_shipping_methods {
          carrier_code
          method_code
          amount { value currency }
        }
      }
    }
  }
}

نصيحة الدفع headless: اطلب دائمًا available_shipping_methods و available_payment_methods بعد تعيين العنوان — تعتمد الأسعار على محتويات السلة والوجهة.


مصادقة العميل

إنشاء token عميل

mutation {
  generateCustomerToken(
    email: "[email protected]"
    password: "Password123!"
  ) {
    token
  }
}

استخدم token في الطلبات اللاحقة:

-H "Authorization: Bearer <token>"
"

تنتهي صلاحية tokens بناءً على تكوين Admin (`Stores → Configuration → Services → OAuth → Customer Token Lifetime`). القيمة الافتراضية هي ساعة واحدة — خطط لمنطق التحديث في واجهتك الأمامية.

**استعلام introspection (للمطورين فقط)**

عطّل introspection في الإنتاج للأمان. في التطوير، استكشف المخطط:

```graphql
{
  __schema {
    types {
      name
      kind
    }
  }
}

أو استخدم GraphQL Playground / Altair / Postman مع تمكين introspection.


بناء محلل استعلام مخصص

عندما لا يكفي المخطط المضمن، وسّعه بوحدة مخصصة.

هيكل الدليل

app/code/MagentoMastery/GraphQlDemo/
├── registration.php
├── etc/
│   ├── module.xml
│   └── schema.graphqls
└── Model/
    └── Resolver/
        └── HelloWorld.php

Query schema.graphqls

type Query {
    helloWorld(name: String): String
      @resolver(class: "MagentoMastery\\GraphQlDemo\\Model\\Resolver\\HelloWorld")
      @doc(description: "Returns a greeting string")
}

فئة المحلل

<?php
declare(strict_types=1);

namespace MagentoMastery\GraphQlDemo\Model\Resolver;

use Magento\Framework\GraphQl\Config\Element\Field;
use Magento\Framework\GraphQl\Query\ResolverInterface;
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;

class HelloWorld implements ResolverInterface
{
    public function resolve(
        Field $field,
        $context,
        ResolveInfo $info,
        ?array $value = null,
        ?array $args = null
    ): string {
        $name = $args['name'] ?? 'World';
        return "Hello, {$name}!";
    }
}

اختبر الاستعلام المخصص

{ helloWorld(name: "Magento") }

بعد النشر:

bin/magento setup:upgrade
bin/magento cache:flush

تتطلب تغييرات مخطط GraphQL مسحًا للذاكرة المؤقتة — يخزن ماجنتو المخطط المجمّع مؤقتًا.


بناء طفرة مخصصة

تتبع الطفرات نفس النمط لكنها تطبق ResolverInterface على حقل من نوع Mutation.

Mutation schema.graphqls

type Mutation {
    subscribeNewsletter(email: String!): NewsletterOutput
      @resolver(class: "MagentoMastery\\GraphQlDemo\\Model\\Resolver\\SubscribeNewsletter")
}

type NewsletterOutput {
    success: Boolean!
    message: String
}

محلل مع التحقق

<?php
declare(strict_types=1);

namespace MagentoMastery\GraphQlDemo\Model\Resolver;

use Magento\Framework\Exception\LocalizedException;
use Magento\Framework\GraphQl\Config\Element\Field;
use Magento\Framework\GraphQl\Exception\GraphQlInputException;
use Magento\Framework\GraphQl\Query\ResolverInterface;
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;

class SubscribeNewsletter implements ResolverInterface
{
    public function resolve(
        Field $field,
        $context,
        ResolveInfo $info,
        ?array $value = null,
        ?array $args = null
    ): array {
        $email = $args['email'] ?? '';

        if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
            throw new GraphQlInputException(__('Invalid email address.'));
        }

        // Subscribe logic here...

        return [
            'success' => true,
            'message' => 'Subscribed successfully.',
        ];
    }
}
"

ارمِ `GraphQlInputException` لأخطاء العميل (مستوى 400) و `GraphQlAuthorizationException` لفشل المصادقة — يقوم ماجنتو بترجمتها إلى استجابات خطأ GraphQL المناسبة.

---

## الأداء والتخزين المؤقت

يمكن أن يكون GraphQL أبطأ من المتوقع إذا طلب العملاء حقولاً متداخلة كثيرة. طبّق هذه القواعد في الإنتاج:

**1. حدد عمق وتعقيد الاستعلام**

استخدم proxy عكسي أو حدود تعقيد الاستعلام المضمنة في ماجنتو (Adobe Commerce) لحظر الاستعلامات المسيئة.

**2. خزن مؤقتًا في CDN للاستعلامات المجهولة**

خزن مؤقتًا فقط الاستعلامات التي لا تتضمن tokens عميل أو معرفات سلة. استعلامات قائمة المنتجات مرشحة جيدة لـ CDN عند مفتاحها بواسطة المتجر + تجزئة الاستعلام.

**3. تجنب N+1 في المحللات المخصصة**

عند تحليل القوائم، استخدم محللات دفعة أو أدوات تحميل بيانات. المحلل البسيط الذي يحمّل نموذج منتج لكل عنصر سيدمر الأداء في صفحات الفئات.

**4. اطلب فقط ما تعرضه**

```graphql
items { sku name description { html } }

items { sku name small_image { url } price_range { minimum_price { final_price { value } } } }

5. حافظ على صحة المفهرسات

يقرأ GraphQL من جداول مسطحة مفهرسة و Elasticsearch. مفهرسات قديمة = استجابات API قديمة. راجع دليل المفهرسات للصيانة.


GraphQL مقابل REST: متى تستخدم ماذا

حالة الاستخدامAPI الموصى به
واجهة متجر / PWA / تطبيق جوالGraphQL
تكاملات الإدارة (طلبات، استيراد كتالوج)REST (Async Bulk API)
مزامنة ERP خارجيةREST
سلة/دفع في الوقت الفعليGraphQL
تكاملات قديمةREST

اتجاه Adobe واضح: GraphQL للعميل، REST للعمليات الخلفية المجمعة.


الأسئلة الشائعة التقنية

أين يُعرف مخطط GraphQL؟

ملفات المخطط الأساسية موجودة في etc/schema.graphqls لكل وحدة. يدمجها ماجنتو في وقت التشغيل. تضيف الوحدات المخصصة ملف etc/schema.graphqls الخاص بها.

هل يمكنني استخدام GraphQL في لوحة الإدارة؟

صُمم GraphQL لعمليات واجهة المتجر. تستخدم وظائف الإدارة REST أو واجهة المستخدم الإدارية — لا تعرض عمليات الإدارة عبر GraphQL مخصص بدون فحوصات ACL صارمة.

كيف أصحح أخطاء GraphQL؟

فعّل وضع المطور وتحقق من var/log/exception.log. يعيد GraphQL الأخطاء في مصفوفة errors من استجابة JSON مع حقلي message و category.

هل يستبدل GraphQL الدفع بـ Knockout.js؟

ليس تلقائيًا. لا يزال دفع Luma قائمًا على Knockout. يتطلب الدفع headless واجهة أمامية تستهلك طفرات GraphQL (React, Vue, Hyvä Checkout, إلخ). راجع دليل الدفع للعمل مع Knockout.js أو بناء بديل headless.

هل GraphQL متاح في Magento Open Source؟

نعم. GraphQL جزء من Magento Open Source منذ 2.3.x. بعض الميزات المتقدمة (حدود تعقيد الاستعلام، معاينات staging) مخصصة لـ Adobe Commerce فقط.


الخاتمة

GraphQL هي طبقة API القياسية لواجهات متاجر ماجنتو 2 الحديثة. أتقن أولاً مخطط المنتجات وسلة التسوق المضمن، ثم وسّعه بمحللات مخصصة عندما تتطلب ذلك منطق الأعمال. حافظ على استعلاماتك خفيفة، ومفهرساتك محدثة، وtokens المصادقة جديدة — وستبقى واجهة متجرك headless سريعة وموثوقة.

هل تبني واجهة متجر headless لماجنتو 2 أو تحتاج نقاط نهاية GraphQL مخصصة؟ اتصل بي لمراجعات الهندسة المعمارية، وحدات مخصصة ، وتحسين الأداء.