פיתוח JSON API עבור 1C-Bitrix במפתח מלא — חוזה קפדני וקישור מטמון
אנו מפתחים JSON API עבור 1C-Bitrix — לא רק "נקודות קצה שמחזירות JSON", אלא חוזה קפדני לפי מפרט jsonapi.org. עם זה, לקוח שמכיר את התקן יכול להתחבר ללא תיעוד נוסף. בניסיון שלנו, זה מקצר את זמן התיאום ב-30% ומבטל אי-בהירות בהעברת נתונים. פרויקט טיפוסי כולל 10–15 נקודות קצה; עלות הפיתוח משתנה בהתאם למורכבות. במקביל, החיסכון בתחזוקה מגיע עד 40% בזכות חוזה אחיד.
יתרונות בהזמנת JSON API
פתרון מוכן מאיץ פיתוח frontend, אפליקציות מובייל ואינטגרציות CRM. אתם מפסיקים להיות תלויים בשינויים פנימיים ברכיבי Bitrix — ה-API חי חיים משלו. ועם מטמון מתויג (tagged cache על אירועי OnBeforeIBlockElementUpdate), עומס השרת יורד פי 3–5 בהשוואה לשיטות REST רגילות. JSON API מהיר וצפוי יותר מה-REST המובנה, במיוחד בעבודה עם קטלוגים של 10,000+ מוצרים.
ארכיטקטורת JSON API על Bitrix
יישום PHP טהור על גבי ליבת Bitrix. נקודת הכניסה היא בקר מחוץ למערכת הרכיבים:
/local/ api/ v1/ router.php — маршрутизация запросов middleware/ AuthMiddleware.php RateLimitMiddleware.php resources/ ProductResource.php — трансформер данных OrderResource.php controllers/ ProductController.php OrderController.php ב-/local/ api/ v1/ router.php — маршрутизация запросов middleware/ AuthMiddleware.php RateLimitMiddleware.php resources/ ProductResource.php — трансформер данных OrderResource.php controllers/ ProductController.php OrderController.php , מוגדרים מסלולים. לדוגמה, עבור מוצרים והזמנות:
$router->get('/v1/products', [ProductController::class, 'index']); $router->get('/v1/products/{id}', [ProductController::class, 'show']); $router->post('/v1/orders', [OrderController::class, 'create']); $router->patch('/v1/orders/{id}', [OrderController::class, 'update']); המרת נתונים ל-JSON API
מחלקת המשאבים ממירה נתונים גולמיים מבלוקי מידע למבנה JSON, ומבודדת את הלקוחות משינויי שדות. דוגמה למוצרים:
class ProductResource { public static function make(array $product, array $include = []): array { $data = [ 'id' => (int)$product['ID'], 'type' => 'products', 'attributes' => [ 'name' => $product['NAME'], 'code' => $product['CODE'], 'description' => $product['DETAIL_TEXT'], 'active' => $product['ACTIVE'] === 'Y', 'created_at' => $product['DATE_CREATE'], ], 'relationships' => [], ]; if (in_array('prices', $include)) { $data['relationships']['prices'] = PriceResource::collection( PriceRepository::getForProduct((int)$product['ID']) ); } if (in_array('sku', $include)) { $data['relationships']['sku'] = SkuResource::collection( SkuRepository::getForProduct((int)$product['ID']) ); } return $data; } } הפרמטר router.php בבקשה שולט בהכללת נתונים קשורים — הלקוח מקבל בדיוק את מה שהוא צריך.
סינון, מיון ודפדוף
כל שלושת המנגנונים מיושמים באמצעות פרמטרי שאילתה. הם עובדים בבלוק קוד אחד ומחזירים מטא-נתונים על מספר הרשומות.
// Фильтрация $filter = ['IBLOCK_ID' => CATALOG_IBLOCK_ID, 'ACTIVE' => 'Y']; if (isset($_GET['filter']['section_id'])) { $filter['SECTION_ID'] = (int)$_GET['filter']['section_id']; } // Сортировка $sort = []; foreach (explode(',', $_GET['sort'] ?? 'id') as $field) { $direction = str_starts_with($field, '-') ? 'DESC' : 'ASC'; $sort[ltrim($field, '-')] = $direction; } // Пагинация (offset-based) $limit = (int)($_GET['page']['size'] ?? 20); $offset = ((int)($_GET['page']['number'] ?? 1) - 1) * $limit; התשובה כוללת מטא-נתונים:
{ "data": [...], "meta": { "total": 1543, "page": 2, "per_page": 20, "last_page": 78 }, "links": { "self": "/v1/products?page[number]=2", "next": "/v1/products?page[number]=3", "prev": "/v1/products?page[number]=1" } } יצירת הזמנה
POST $router->get('/v1/products', [ProductController::class, 'index']); $router->get('/v1/products/{id}', [ProductController::class, 'show']); $router->post('/v1/orders', [OrderController::class, 'create']); $router->patch('/v1/orders/{id}', [OrderController::class, 'update']); עם גוף הבקשה:
{ "data": { "type": "orders", "attributes": { "delivery_address": "Москва, ул. Пушкина, 1", "payment_method": "card" }, "relationships": { "items": { "data": [ { "type": "order-items", "product_id": 123, "quantity": 2 }, { "type": "order-items", "product_id": 456, "quantity": 1 } ] } } } } הבקר מאמת נתונים וקורא ל-class ProductResource { public static function make(array $product, array $include = []): array { $data = [ 'id' => (int)$product['ID'], 'type' => 'products', 'attributes' => [ 'name' => $product['NAME'], 'code' => $product['CODE'], 'description' => $product['DETAIL_TEXT'], 'active' => $product['ACTIVE'] === 'Y', 'created_at' => $product['DATE_CREATE'], ], 'relationships' => [], ]; if (in_array('prices', $include)) { $data['relationships']['prices'] = PriceResource::collection( PriceRepository::getForProduct((int)$product['ID']) ); } if (in_array('sku', $include)) { $data['relationships']['sku'] = SkuResource::collection( SkuRepository::getForProduct((int)$product['ID']) ); } return $data; } } דרך ממשק D7 של מודול ?include=prices,sku. במקרה של שגיאה — תשובת 422 Unprocessable Entity עם רשימת שגיאות מובנית.
אימות זהות
-
סשן Bitrix. לבקשות מאפליקציות דפדפן שבהן המשתמש מחובר לאתר. אנו בודקים
// Фильтрация $filter = ['IBLOCK_ID' => CATALOG_IBLOCK_ID, 'ACTIVE' => 'Y']; if (isset($_GET['filter']['section_id'])) { $filter['SECTION_ID'] = (int)$_GET['filter']['section_id']; } // Сортировка $sort = []; foreach (explode(',', $_GET['sort'] ?? 'id') as $field) { $direction = str_starts_with($field, '-') ? 'DESC' : 'ASC'; $sort[ltrim($field, '-')] = $direction; } // Пагинация (offset-based) $limit = (int)($_GET['page']['size'] ?? 20); $offset = ((int)($_GET['page']['number'] ?? 1) - 1) * $limit;. -
אסימון Bearer (JWT). ללקוחות מובייל ולשרת-לשרת. Middleware מפענח JWT, מקבל
{ "data": [...], "meta": { "total": 1543, "page": 2, "per_page": 20, "last_page": 78 }, "links": { "self": "/v1/products?page[number]=2", "next": "/v1/products?page[number]=3", "prev": "/v1/products?page[number]=1" } }, ומאתחל סשן Bitrix:
$userId = $jwt->getClaim('sub'); \CUser::SetCurrent($userId); לאחר מכן, כל בדיקות ההרשאות הסטנדרטיות פועלות כראוי.
-
מפתח API. לשותפי B2B. מפתח בכותרת
/v1/orders, מקושר למשתמש או לקבוצה ב-Bitrix.
אימות קלט
לפני העברה למודולים — אימות קפדני. לכל נקודת קצה יש מחלקת Request עם חוקים:
class CreateOrderRequest { public function validate(array $data): array { $errors = []; if (empty($data['delivery_address'])) { $errors[] = ['pointer' => '/data/attributes/delivery_address', 'detail' => 'Обязательное поле']; } if (!in_array($data['payment_method'] ?? '', ['card', 'cash', 'invoice'])) { $errors[] = ['pointer' => '/data/attributes/payment_method', 'detail' => 'Недопустимое значение']; } return $errors; } } שגיאות מוחזרות בפורמט JSON API Errors:
{ "errors": [ { "status": "422", "source": { "pointer": "/data/attributes/delivery_address" }, "title": "Ошибка валидации", "detail": "Обязательное поле" } ] } קישור מטמון תשובות
עבור בקשת GET, אנו מגדירים מטמון HTTP דרך כותרות:
header('Cache-Control: public, max-age=600, s-maxage=3600'); header('ETag: "' . md5($cacheKey . $dataHash) . '"'); בצד Bitrix — מטמון מתויג לנתונים מצטברים. כאשר מוצר מתעדכן מחילופי 1C, התגית נפסלת, והבקשה הבאה מביאה נתונים טריים ממסד הנתונים.
מה כלול בעבודה
- עיצוב משאבים ונקודות קצה
- פיתוח Router, Middleware ואימות זהות
- יישום משאבי קטלוג (מוצרים, SKU, מחירים, מלאי)
- פעולות מסחר (עגלה, הזמנות, תשלום)
- נקודות קצה למשתמש (אימות, פרופיל, היסטוריית הזמנות)
- קישור מטמון (כותרות HTTP, Redis, מטמון מתויג)
- תיעוד OpenAPI + אוסף Postman
- בדיקות אינטגרציה ובדיקות עומס
- קוד ב-Git, הוראות פריסה
שלבי פיתוח
| שלב | תוכן | משך |
|---|---|---|
| עיצוב | משאבים, נקודות קצה, פורמט נתונים | שבוע |
| תשתית | Router, Middleware, אימות זהות | שבוע |
| משאבי קטלוג | מוצרים, SKU, מחירים, מלאי, קטגוריות | 1–2 שבועות |
| פעולות מסחר | עגלה, הזמנות, תשלום | 1–2 שבועות |
| נקודות קצה למשתמש | אימות, פרופיל, היסטוריית הזמנות | שבוע |
| קישור מטמון | כותרות HTTP, Redis, מטמון מתויג | שבוע |
| תיעוד | OpenAPI, אוסף Postman | 3–5 ימים |
| בדיקות | בדיקות אינטגרציה, בדיקות עומס | שבוע |
פרטי ארכיטקטורת מטמון
אנו משתמשים במטמון מתויג של Bitrix: כאשר רכיב בלוק מידע נשמר, האירוע `OnAfterIBlockElementAdd` מופעל, מה שמפסיל את המטמון לפי התגית `iblock_id_XXX`. זה מבטיח טריות נתונים ללא איפוס ידני.JSON API על Bitrix הוא חוזה קפדני וצפוי שחי באופן עצמאי מגרסאות רכיבים ותבניות. עם יישום נכון, צוות ה-frontend עובד עם ה-API כשירות עצמאי. כל הבקשות מתועדות, שגיאות מוחזרות בפורמט סטנדרטי, וגרסאות מגנות על לקוחות משינויי סכמה בלתי צפויים.
העריכו את הפרויקט שלכם בחינם. צרו קשר — ננתח את הדרישות ונציע ארכיטקטורה עם לוחות זמנים. קבלו ייעוץ ממהנדס עם ניסיון של למעלה מ-10 שנים ב-Bitrix.







