בדיקת חוזה
1) היכן ליישם חוזים
HTTP REST/JSON: משאבים, הפגנות, מסננים, אידמפוטנטיות, קודי שגיאה.
GRPC/Protobuf: סוגי הודעות, סטטוסים, סמנטיקה 'דדליין', V.proto-compat לאחור.
תרשימים: לא מבוטלים, הנחיות, מתירניים לשדות.
הודעות/זרמים (Kafka/Pulsar/SQS): תרשימי אירועים (Avro/JSON/Protobuf), מפתחות מחיצה, סדר, מפתחות אידמפוטנטים.
Internal SDKs/Libraries: Public Features/Exceptions/Performance Contracts.
2) מודל CDC: תפקידים וחפצים
הצרכן מפרסם את חוזה הציפיות (בקשות/תגובות מדגם, מטפלים סוג, אינווריאנטים).
הספק מפעיל אימות חוזה כנגד השירות/מתאם/מפעילים שלו.
ברוקר החוזים (Pact Broker/Backage/repo prect) אוגר גרסאות, תגיות ('prod',' staging ',' canary ') ומטריצת התאימות של הצרכן @ v.
מדיניות שחרור: שליחת ספק אסורה אם כל חוזה ”פרוד-רלוונטי” מופר.
3) מה לתקן בחוזה (דוגמה מ ־ HTTP)
מינימום:- שיטה/נתיב/פרמטרים/כותרות (incl. Auth, idempotent key).
- Body and טיפוסי matchers (סוג/פורמט/regexp/ranges).
- קודי שגיאה ומבנה; Stable 'error _ code'.
- אינווריאנטים סמנטיים: מיון, ייחודיות, מונוטוניות ”נוצר _ at”.
- ציפיות לא פונקציונליות (אופציונליות): p95, מגבלות גודל, כותרות מגבלות קצב.
json
{
"interaction": "GET /v1/users/{id}",
"request": { "method": "GET", "path": "/v1/users/123", "headers": {"Accept":"application/json"} },
"matchers": {
"response.body.id": "type:number",
"response.body.email": "regex:^.+@.+\\..+$",
"response.body.created_at": "format:rfc3339"
},
"response": {
"status": 200,
"headers": {"Content-Type":"application/json"},
"body": {"id": 123, "email": "alice@example.com", "created_at": "2025-10-31T12:00:00Z"}
},
"error_cases": [
{
"name":"not_found",
"request":{"path":"/v1/users/9999"},
"response":{"status":404, "body":{"error_code":"USER_NOT_FOUND"}}
}
]
}
4) חוזים מונעי אירועים
סכימת אירוע: 'סוג', 'גרסה', 'id',' התרחש _ at _ utc ',' מפיק ',' נושא ',' Pirload '.
אינווריאנטים: infariance 'id' and idempotence by' (סוג, id), סדר בתוך המפתח של החלק, מונוטוני 'רצף'.
Schema Registry-Stors אבולוציה וכללי תאימות (אחורה/קדימה/מלא).
מבחני חוזה צרכני: שידור חוזר של אירועים ”מוזהבים” ושלבים של תשלילים (שדות לא ידועים, נאול).
json
{
"type":"record","name":"UserRegistered","namespace":"events.v1",
"fields":[
{"name":"id","type":"string"},
{"name":"occurred_at_utc","type":{"type":"long","logicalType":"timestamp-millis"}},
{"name":"email","type":"string"},
{"name":"marketing_opt_in","type":["null","boolean"],"default":null}
]
}
5) אבולוציה ותאימות
גרסאות חוזה: סמנטיקה ”סרן”. מינורי. פאץ '(מייג' ור - שבירה).
חוקים למנוחה:- אל תשבור: אל תמחק שדות, אל תשנה את סוג/ערך ”שגיאה _ קוד”.
- הוסף שדות אופציונליים עם ברירת מחדל; נקודות קצה חדשות במקום ”קסם”.
- הצהרה, תמיכה משותפת, מחיקה על ידי מדדים.
- GraphQL: הוספת שדות בלבד, הזנה לא מבוטלת דרך פאזות; קביעת הנחיות.
- GRPC/Proto: אל תשתמש שוב במספרי שדה; רק להוסיף חדשים עם אופציונלי.
- אירועים: ערכת "vN'; הצרכנים נדרשים להתעלם משדות לא ידועים (סלחנות).
6) בדיקות שליליות ואינווריאנטיות
שלילי: סוגים שגויים, ערכים אסורים, פרמטרים סותרים, מעבר לגבולות.
אינווריאנטים: מיון של תגובות, ייחודיות של ”id', תקינות של” next _ corress', יציבות של תגובה אידמפוטנטית בעת החזרה.
חוזים של היבטים זמניים: "נוצר _ at' RFC3339/UTC, ההשלכה הנכונה של ימים מקומיים אינה חלק מחוזה ההובלה - מוגשת לאינווריאנטים עסקיים.
7) דור דקירה ופיתוח מקומי
מחוזים, ערימות הספקים נוצרות עבור פיתוח צרכני.
עבור אירועים - מחוללי מסרים ”תקפים/גבוליים” לפי התוכנית.
צוותים מסומנים בגרסת החוזה ותאריך הבנייה; פרסום בפרוד.
8) שיבוץ ב ־ CI/CD (צינור התייחסות)
1. מודיע לצרכן:
Mint/Build = process generation project/test project (tag: 'consess @ 1. 7. 0`).
2. ספק מודיע:
מעלה את השירות באופן מקומי/במיכל * הבא את החוזים הרלוונטיים ('prod'/' staging').
3. שחרור שער:
פריסת הספק חסומה אם יש חוזים בולטים.
4. מטריקס לילי:
מטריצת תאימות ”גרסאות צרכניות × גרסאות ספקיות”; דיווחים ואזעקות.
9) דוגמאות למנהגים בתחום
9. 1 מנוחה: סמן פגינציה (חוזה אינווריאנט)
התגובה מכילה "פריטים [ ]", "next _ colress' (nullable)," limit "," total "(אופציונלי).
Invariants: 'len (פריטים) lood limit', שיחה חוזרת עם אותה 'סמן' = idempotent set.
שגיאה אם ”cursor” ו- ”page” הם שניהם מצוינים.
9. 2 אידמפוטנטיות פוסט
החוזה דורש כותרת 'Idempotency-Key'.
אינווריאנט: שאילתה חוזרת עם אותו מפתח מחזירה את אותו 'id'/סטטוס.
9. 3 אירועים: ערבויות לסדר
מקש המחיצה בחוזה הוא 'מחיצה _ מפתח = user_id'.
אינווריאנט: ”רצף” גדל באופן מונוטוני בתוך המפתח; הצרכן חייב לטפל בהילוכים החוזרים.
10) ביטחון ופרטיות בחוזים
אל תכלול מידע/סודות אישיים בדוגמאות - רק סינתטיים.
תיקון כותרות אבטחה חובה: ”אישור”, ”X-חתימה”, ”Replay-מניעה”.
עבור חוברות אינטרנט - חתימה וחוזה תגובה '2xx '/מגשים מחדש.
ביומנים של בדיקות חוזה - מסווה שדות רגישים.
11) כלים
Pact/Pactflow/Pact Broker - חוזי HTTP/Message, מטריצת תאימות.
OpenAPI/ASyncAPI - מפרטים + מחוללי בדיקה (Dred, Schemathesis).
קראטה/מנוחה בטוחה - בדיקות תרחיש של חוזי מנוחה.
Protobuf/gRPC - 'buf', 'protolint', מבחני תאימות; סכימה רישום עבור Avro/JSON/Proto בנחלים.
מבחני קונפורמציה עבור GraphQL (Graphql-compat), מבחני מעגל.
12) פסאודוקודה של אימות ספק (מפושט)
python def verify_contract(provider, contract):
for case in contract["cases"]:
req = build_request(case["request"])
res = provider.handle(req) # локально/контейнер assert match_status(res.status, case["response"]["status"])
assert match_headers(res.headers, case["response"].get("headers", {}))
assert match_body(res.body, case["matchers"], allow_extra_fields=True)
for neg in contract.get("error_cases", []):
res = provider.handle(build_request(neg["request"]))
assert res.status == neg["response"]["status"]
assert res.json.get("error_code") == neg["response"]["body"]["error_code"]
13) אנטי דפוסים
”צילומי מסך של דוור הם חוזה”: אין גרסאות/טיפוסי מטפלים/אימות אוטומטי.
תנודות יתר: החוזה מתקן ערכים מדויקים במקום טיפוסים/דפוסים.
חוזה משותף אחד לאזורים/ערוצים שונים: מתעלם מהשונות (דגלים, geo-rules).
חוזים ללא ברוקר/מטריקס: לא ניתן להבין אילו גרסאות מתאימות.
הימור על e2 במקום חוזים: איטי, יקר, לא יציב.
אין מקרים שליליים/אינווריאנטיים: רק ”המסלול הירוק” נבחן.
14) יכולת תצפית ותפעול
ייצוא מעמד לברוקר + לוח מחוונים ”חוזי בריאות”.
התראות: טיפות חדשות במספק נגד חוזים 'Prod', עלייה ב ”שדה לא ידוע” באירועים.
עקבות: ”חוזה _ id',” גרסה ”,” החלטה _ id' ברישומי אימות.
15) תהליך דיכאון
1. הוספת שדה/נקודת סוף (אי שבירה).
2. סמן את הישנים כ ”מיושנים” במפרט, הכרז על התאריכים.
3. מעקב אחר צרכנים על ידי יומנים/ברוקר; מדריכי נדידה.
4. אפשר ”צל” להכחיש בבמה (יבשה), ואז לאכוף.
5. מחק לאחר אפס שימוש ותאימות.
16) רשימת אדריכלים
1. צרכנים ובעליהם זוהו? חוזים מבוססים?
2. האם יש ברוקר ומטריצת תאימות עם תגי סביבה?
3. האם נגטיבים ואינווריאנטים (אידיוטים, קורסים, מיון) כלולים בחוזה?
4. האם סכימה רישום ותאימות מצב מוגדר לאירועים?
5. צינור חוסם את שחרור הספק במקרה של הפרת חוזי ייצור?
6. האם תהליך הפחת ומדיניות האבולוציה מתואר?
7. דקירות נוצרות מחוזים, האם יש מחוללי אירועים מקומיים?
8. האם מסכות פ "ד וכותרות בטיחות חובה מתועדות?
9. מדדים/התראות על חוזים מחוברים, האם יש דוחות סחף?
10. החוזים נבחנים ב-CI על ידי שני הצדדים (הצרכן והספק)?
מסקנה
בדיקת חוזה מעבירה ”אמת” על אינטראקציות לחפצים ממולאים והופכת את האינטגרציה לחיזויה. CDC, ברוקר חוזה, ודיסציפלינת אבולוציה מזימה מחליפים את ”שבירת הפתעות” בתהליך מנוהל: בדיקות מהירות, אינווריאנטים ברורים ותאימות גירסה שקופה. זה מוריד את העלות של e2e, מאיץ משחרר ומשפר את איכות הפלטפורמה כולה.