דלגו לתוכן

או התחילו מנקודה בטוחה: אינדקס הכלים המלא · מפת הטבלאות המרכזיות

מערכת חדשה — 14 יום חינם

batch — כמה פעולות בבקשה אחת

עודכן 30.08.2026
POST /parse/batch

batch אורז כמה פעולות CRUD לבקשת HTTP אחת. הרווח הוא בעיקר בזמן רשת: במקום 50 סבבי הלוך‑חזור, אחד.

מה batch הוא לא: הוא אינו טרנזקציה. אין rollback, אין אטומיות. כל פעולה נכשלת או מצליחה בנפרד, וההצלחות נשארות.

JSON
{
"requests": [
{ "method": "POST", "path": "/parse/classes/Accounts",
"body": { "Name": "לקוח א", "PhoneNumber": "0501111111", "IsAccount": false } },
{ "method": "PUT", "path": "/parse/classes/Accounts/xK9mP2qRsT",
"body": { "IsAccount": true } },
{ "method": "DELETE", "path": "/parse/classes/Accounts/Cpl9lrueY5" }
]
}
שדה חובה הערות
requests מערך. המלצת המוצר: עד 50 איברים — לא נאכף, ראו למטה
requests[].method POST · PUT · DELETE
requests[].path הנתיב המלא כולל /parse — למשל /parse/classes/Tasks
requests[].body ל‑POST ו‑PUT אותו גוף בדיוק כמו בקריאה בודדת, כולל עטיפות Pointer ו‑Date

הכותרות (X-Parse-Application-Id ואישור ההרשאה) נשלחות פעם אחת, על הבקשה כולה.

Bash
curl -sS -X POST "https://api.mbapps.co.il/parse/batch" \
-H "X-Parse-Application-Id: $APP_ID" \
-H "X-Parse-API-Key: $API_KEY" \
-H "Content-Type: application/json" \
-d '{"requests":[
{"method":"POST","path":"/parse/classes/Tasks",
"body":{"Name":"התקשר ללקוח",
"AccountId":{"__type":"Pointer","className":"Accounts","objectId":"xK9mP2qRsT"}}}
]}'
JavaScript
const APP_ID = process.env.APP_ID, API_KEY = process.env.API_KEY;
const res = await fetch('https://api.mbapps.co.il/parse/batch', {
method: 'POST',
headers: {
'X-Parse-Application-Id': APP_ID,
'X-Parse-API-Key': API_KEY,
'Content-Type': 'application/json',
},
body: JSON.stringify({
requests: [
{
method: 'POST',
path: '/parse/classes/Tasks',
body: {
Name: 'התקשר ללקוח',
AccountId: { __type: 'Pointer', className: 'Accounts', objectId: 'xK9mP2qRsT' },
},
},
],
}),
});
const data = await res.json();
Python
import os, requests
APP_ID = os.environ["APP_ID"]
API_KEY = os.environ["API_KEY"]
res = requests.post(
"https://api.mbapps.co.il/parse/batch",
headers={
"X-Parse-Application-Id": APP_ID,
"X-Parse-API-Key": API_KEY,
"Content-Type": "application/json",
},
json={
"requests": [
{
"method": "POST",
"path": "/parse/classes/Tasks",
"body": {
"Name": "התקשר ללקוח",
"AccountId": {"__type": "Pointer", "className": "Accounts", "objectId": "xK9mP2qRsT"},
},
},
],
},
)
data = res.json()
PHP
<?php
$appId = getenv('APP_ID');
$apiKey = getenv('API_KEY');
$ch = curl_init();
curl_setopt_array($ch, [
CURLOPT_URL => "https://api.mbapps.co.il/parse/batch",
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
"X-Parse-Application-Id: $appId",
"X-Parse-API-Key: $apiKey",
"Content-Type: application/json",
],
CURLOPT_POSTFIELDS => json_encode([
"requests" => [
[
"method" => "POST",
"path" => "/parse/classes/Tasks",
"body" => [
"Name" => "התקשר ללקוח",
"AccountId" => ["__type" => "Pointer", "className" => "Accounts", "objectId" => "xK9mP2qRsT"],
],
],
],
], JSON_UNESCAPED_UNICODE),
]);
$response = curl_exec($ch);
curl_close($ch);
$data = json_decode($response, true);

מבנה התשובה — וזו הנקודה החשובה

Section titled “מבנה התשובה — וזו הנקודה החשובה”

התשובה היא מערך באותו סדר של הבקשות. כל איבר מכיל success או error:

JSON
[
{ "success": { "objectId": "aB3dEf9HiJ", "createdAt": "2026-08-20T09:00:00.000Z" } },
{ "success": { "updatedAt": "2026-08-20T09:00:00.100Z", "objectId": "xK9mP2qRsT" } },
{ "error": { "code": 101, "error": "Object not found." } }
]
Python
import requests
API = "https://api.mbapps.co.il/parse"
H = {"X-Parse-Application-Id": APP_ID,
"X-Parse-API-Key": API_KEY,
"Content-Type": "application/json"}
def run_batch(operations: list[dict]) -> tuple[list, list]:
"""מריץ אצווה ומחזיר (הצלחות, כישלונות-עם-הבקשה-המקורית)."""
assert len(operations) <= 50, "גודל אצווה מומלץ: 50 (השרת לא יעצור אתכם)"
r = requests.post(f"{API}/batch", headers=H, json={"requests": operations}, timeout=60)
r.raise_for_status() # תופס רק כשל של הבקשה כולה
ok, failed = [], []
for op, result in zip(operations, r.json()):
if "success" in result:
ok.append(result["success"])
else:
failed.append({"request": op, "error": result.get("error")})
return ok, failed

חתכו בצד הלקוח:

Python
import time
def chunks(seq, size=50):
for i in range(0, len(seq), size):
yield seq[i:i + size]
def create_all(table: str, rows: list[dict], pause: float = 0.3):
ops = [{"method": "POST", "path": f"/parse/classes/{table}", "body": row} for row in rows]
created, errors = [], []
for group in chunks(ops, 50):
ok, bad = run_batch(group)
created += ok
errors += bad
time.sleep(pause) # אין מגבלות קצב מתועדות — האטה מרצון
return created, errors

טריגרים — המלכודת האמיתית של batch

Section titled “טריגרים — המלכודת האמיתית של batch”

ל‑POST /parse/batch אין דגל להשתקת טריגרים. אין skipTriggers, אין skipTimeline — דגלים כאלה ברמת הבקשה פשוט מתעלמים מהם: batch עם "skipTriggers":true מפעיל את הטריגר על כל רשומה, וכל רשומה מקבלת 3 שורות _Timeline.

מה כן אפשר:

הדרך איך ההגבלה
כיבוי זמני של הטריגר סביבת פיתוח ← Databases ← המערכת ← Triggers — לכל טריגר יש עמודת Active. דרך MCP: Set-Trigger עם "active": false דורש תיאום עם מי שמחזיק את האוטומציות; אל תשכחו להדליק חזרה
תיאום מראש להריץ בשעה שבה שליחה החוצה לא מזיקה הפתרון הפחות אלגנטי והכי בטוח
הכלי Create-Many של MCP {"table":"Accounts","data":[…],"skipTriggers":true,"skipTimeline":true} שני הדגלים מכובדים רק באימות Master Key. בגרסאות שרת ישנות הכלי היה חסום, ראו למטה

1 · הנתיב חייב לכלול /parse

Section titled “1 · הנתיב חייב לכלול /parse”
JSON
{ "method": "POST", "path": "/classes/Accounts" } // ✘ 400 {"code":107,"error":"cannot route batch path /classes/Accounts"}
{ "method": "POST", "path": "/parse/classes/Accounts" } // ✔

ושגיאות מבנה נוספות — חלקן מפילות את כל הבקשה (400), וחלקן חוזרות כ‑error של איבר בודד בתוך 200:

הבקשה התשובה
requests חסר או אינו מערך 400{"code":107,"error":"requests must be an array"}
method שאינו POST/PUT/DELETE (למשל PATCH) 400{"code":107,"error":"cannot route PATCH /classes/…"}
GET בתוך batch 200, והאיבר: {"error":{"error":"Cannot convert undefined or null to object"}}
POST בלי body 200, והאיבר: אותה שגיאה — Cannot convert undefined or null to object
requests: [] 200 עם []

2 · הגוף הוא אותו גוף — כולל העטיפות

Section titled “2 · הגוף הוא אותו גוף — כולל העטיפות”

batch אינו שכבה חדשה. Pointer עדיין אובייקט עטוף, ותאריך עדיין {"__type":"Date","iso":…}:

JSON
{
"method": "POST",
"path": "/parse/classes/Tasks",
"body": {
"Name": "מעקב הצעת מחיר",
"Date": { "__type": "Date", "iso": "2026-09-01T08:00:00.000Z" },
"AccountId": { "__type": "Pointer", "className": "Accounts", "objectId": "xK9mP2qRsT" }
}
}
המצב מה עדיף
הפעולות תלויות זו בזו (יצירת לקוח ואז משימה שמקושרת אליו) שתי קריאות רצופות — ה‑objectId מהראשונה נחוץ לשנייה, ו‑batch לא מזין תוצאות ביניהן
צריך אטומיות (“הכול או כלום”) batch לא נותן זאת. הרכיבו פיצוי בקוד שלכם
טעינה של אלפי רשומות שאסור שתפעיל אוטומציות כיבוי זמני של הטריגרים בתיאום, או חלון שקט
קריאה בלבד batch הוא לכתיבות. GET בתוך batch מוחזר כשגיאה. לקריאה — שאילתות
  1. אצווה של עד 50 פעולות; חתכו בצד שלכם — השרת לא יעצור אתכם.
  2. path מתחיל ב‑/parse.
  3. עברתם על כל איבר בתשובה ובדקתם success מול error.
  4. שמרתם את הבקשה המקורית לצד כל כישלון, כדי שיהיה מה לנסות שוב.
  5. שאלתם מי מחזיק את הטריגרים של הטבלה — לפני שהרצתם.
  6. הוספתם השהיה קצרה בין קבוצות.