Table of Contents
מדוע עיצוב API דורש את ה- Interface Segregation Principle
מערכות תוכנה מודרניות לחיות או למות על ידי ממשקי API שלהם.בין אם אתה בונה שירות RESTful, GraphQL קצהpoint, או קבוצה של SDKs עבור הצריכה הפנימית, ההחלטות שאתה מקבל בשקדת עיצוב הממשק שלך לכל לקוח שנוגע בהם.אחת הדרכים היעילות ביותר לשמור על ה- API שלך נקי, שומרון וידידותי למפתח הוא ליישם את ה-FLT:0 Interfaceation Segal Reregation Pregation Pregrin (Frination PLC) 1SPIplerin (Frin) 1SPIplerin (R) 1 (FER) 1 (FER) 1SPISPISPISPILT:1Frind)
(ה) הוא הרביעי מבין חמשת ה-FLT:0.SOLIDIRLT:1 (עקרונות של עיצוב מוכוון-אובייקט, שהוצג במקור על ידי רוברט C. Martin בסוף שנות ה-90, בעוד שהעיקרון הוסגר לשיעורים וממשקים בשפות כמו Java או C++, ההנחיות שלו ניתנות להעברה ישירה – ואף יותר קריטיות – לתכנון.
במונחים של API, זה מתורגם לתכנון נקודות קצה צרות וממוקדות ולא מונותי, ממשקים בודדים.על ידי כך, אתה להפחית הפיכה, לשפר את הבהירות, ומאפשר לכל לקוח אינטראקציה רק עם החלקים של הממשק שחשוב לו. מאמר זה לוקח לצלול עמוק לתוך מה ISP אומר עבור מעצבי API, כיצד ליישם אותו ביעילות, ומדוע למנוע את הפיתוי של ממשקי השומן ארוך דיבידנדים.
הבנת ה- Interface Segregation Principle
מקור והרעיון הליבה
עיקרון ה- Interface Segregation Principle יצא מההתבוננות כי ממשקים גדולים, "שומן" נוטים לצבור אחריות לאורך זמן. ממשק אחד מטפל בקריאה, כתיבה, עדכון, מחיקה, אימות, כניסה, וביקורת על כוחות כל הצרכנים להיות מודעים - ופוטנציאלי ליישם - כל אחת מהשיטות הללו, גם אם הם רק צריכים לקרוא פעולות.
ISP תומך בפיצול ממשקים כה מפוצצים לקטן, ייתכן שיש לך "נתונים נתונים":0 חוזים ספציפיים ל-"Diger" 1, במקום ממשק אחד של "Datamanager", ייתכן שיהיה לך "DataWriter", "DataWriter", "DataDeleter", ו-"לקוחות של Auditor" תלויים רק בממשקים שתואמים את צרכיהם המדויקים את ההשפעה של המערכת.
ISP בקונטקסט של עיצוב API
בעת תכנון APIs, חשבו על "פניות" כחוזה בין השירות שלכם לבין הצרכנים שלו - בין אם הצרכנים האלה הם יישומים מלפנים, מיקרו-שירותים אחרים, או מפתחי צד שלישי. A API עם עשרות נקודות קצה, או GraphQL schema עם סוג מוטציה אחד, יכול להפוך ל"ממשק שומן".
ISP עוזר לך לשאול: "האם אני יכול לשבור את זה חוזים קטנים ועצמאיים?", התשובה מובילה לעתים קרובות לגרסה נקייה יותר, בדיקות קלות יותר, וכדאיות טובה יותר.לדוגמה, ממשק API שפונה לציבור עלול לחשוף ממשק לקריאה קל עבור לקוחות ניידים תוך מתן ממשק כתיבה עשיר יותר עבור כלי ניהול פנימיים.
היתרונות העיקריים של הפעלת ISP ב- API שלך
חווית פיתוח משופרת (DX)
ממשקי Narrow קלים יותר ללמידה ושימוש.מפתחים חדשים ל- API שלך יכולים לאתר במהירות נקודות קצה או פעולות רלוונטיות למשימה שלהם מבלי להתכווץ באמצעות פונקציונליות לא רלוונטית.זה מקטין עומס קוגניטיבי ומהירויות של אינטגרציה.לדוגמה, שער תשלום שחשוף ממשקים נפרדים להרשאה, לכידת, החזר ו- רִיק הוא הרבה יותר אינטואיטיבי מאשר נקודת קצה של "/משימה אחת הדורשת תשלום מורכב כדי להבחין פעולות.
גמישות מוגברת ויציבות
כאשר ממשקים הם קטנים וממוקדים, שינויים בחלק אחד של המערכת יש השפעה מינימלית על אחרים.אם אתה צריך להוסיף יכולת חדשה לממשק הקריאה - למשל, הדמיה או סינון אפשרויות - ממשק הכתיבה נשאר בלתי נסבל.
שמירה טובה יותר ומבחן
ממשקים קטנים יותר קלים ללעג, להזיז ולמבחן בבידוד.עבור צוותים חוזרים, זה אומר שאתה יכול לזהות כל חוזה קצה מבלי לסובב את ערערת היישום כולה. עבור צוותים בצד הלקוח, חוזים צרים להפחית את שטח פני השטח עבור בדיקות אינטגרציה.התוצאה היא לולאות משוב מהירות יותר ופחות פגמים.
צמצום קופסלינג ותלוי בגוש
ממשקי שומן יוצרים תלות בלתי מחייבת. אפליקציה ניידת שרק צריכה לקרוא פרופילים של משתמשים לא צריכה להיות תלויה בספריה או בשכבת תחבורה הכוללת כתיבת ומחיקה של יכולות.ISP מקטין את ההפיכה הזו, מה שהופך אותה לבטוחה יותר לפתח הן את ה- API והן את הצרכנים באופן עצמאי.באדריכלות מיקרו-שירות, עיקרון זה קריטי לשמירה על אוטונומיה בשירות.
יישום ISP בעיצוב API: אסטרטגיות מעשיות
1.זיהוי תפקידי הלקוח
הצעד הראשון הוא להבין מי הלקוחות של ה- API שלך ומה הם מבצעים בפועל.
- (ב) ,0) צרכנים בלבד (קרא: 1) (לדוגמה, יישומים ניידים המציגים נתונים)
- (ב) ,0,Write-Only ConsumersFLT:1 (למשל, מעבדי ייבוא)
- (ב) [15] לקוחות נוספים (ב) ,(א) ,מ"ר) , (ב) , ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇
- (ב) ,0) מפתחי צד שלישי (הראשונה) אשר עשויים לדרוש רק חלק מתכונות
ממפה כל תפקיד לפעילות הספציפית שהיא דורשת, זה חושף גבולות טבעיים להפרדה.
השתמש ב-Partd Endpoints או משאבים נפרדים
ב- REST, ליצור נקודות קצה ייעודיות עבור אחריות נפרדת, במקום משאב יחיד "/Api/orders' מטפל בכל דבר, לשקול פיצול:
- "GET / Api / הזמנות" - הזמנות רשימה (קריאה)
- "POST/Api/orders" - יצירת סדר (כתיבה)
- "GET / Api /orders / Lidus" - לבדוק מצב (קריאה, התמחות)
- "PATCH/api/orders/Eid cancel" - ביטול ההזמנה (כתיבה, היקף)
כל נקודת קצה הופכת למיני-פנים עם הסימנטיקה שלה.זהו יישום ישיר של ISP ברמת המשאבים.
מינוף (לא אינרציה) עבור Interfaces
בעת תכנון חוזים פנימיים של API (למשל, ב- SDK או שכבת שירות), העדיפו ממשקים קטנים שניתן להלחין.לדוגמה, ב- TypeScript או Java, להגדיר:
interface OrderReader {
getOrder(id: string): Promise<Order>;
listOrders(filter: OrderFilter): Promise<Order[]>;
}
interface OrderWriter {
createOrder(data: CreateOrderInput): Promise<Order>;
updateOrder(id: string, data: UpdateOrderInput): Promise<Order>;
}
// A composite interface for admin use
interface OrderAdmin extends OrderReader, OrderWriter {
deleteOrder(id: string): Promise<void>;
}
דפוס זה מבטיח ללקוחות להיות תלויים רק במה שהם צריכים.שירות יכול ליישם רק את הממשקים הרלוונטיים, הימנעות מגמגמות שיטה לא בשימוש.
4. בנפרד לקרוא ולכתוב מודלים (CQRS)
עבור תחומים מורכבים, לשקול אימוץ (FLT:0)Command Query אחריות Segregation (CQRS)FLT:1 .CQRS הוא סגנון אדריכלות אשר באופן טבעי לאכוף ISP על ידי הפרדה מודלים לקריאה (queries) ממודלים כתובים (commands) ה- API שלך חושף נקודות קצה נפרדות או ערוצים עבור שאילתות ו פקודות.זוהי דרך עוצמתית להבטיח כי לעולם לא משתמשים בשיטות שאינן בשימוש.
השתמש ב- Granular Permissions עם Access מבוסס-תפקיד
ISP חל גם על אבטחה.במקום מפתח חד-ממדי יחיד המענק את כל היכולות, מנפיק אסימונים או מפתחות API המגבילים גישה לממשקים ספציפיים.לדוגמה, ללקוח ציבורי יכול רק לקבל רשות להתקשר ל-'GET/products', בעוד שמערכת פנימית יכולה גם לקרוא ל-'POST/products'.
דוגמאות אמיתיות ל-ISP בפעולה
RESTful APIs: GitHub, Twilio, Stripe
(הספקים העיקריים של ISP.FLT:0GitHub של APIsFeloph:1) יש נקודות קצה ייעודיות עבור קידוד, בעיות, משיכה ופעולות - אתה אף פעם לא צריך להשתמש שיטה לניהול בקשות למשוך בקשות כאשר אתה רק רוצה רשימה של בעיות.FLT:2Twilio's APIF3LTs, קול, אימות ואימות ל-codes5 נקודות זכות שונות.
ראה את ה-API של TEFLT:0 ,1 , כדי לראות כיצד הם נמנעים ממשקי שומן.
גרף ו-ISP
ייתכן ש- GraphQL עשוי בתחילה להפר את ISP מכיוון שנקודת קצה אחת חושפת את כל הschema. עם זאת, ממשקי API מעוצבים היטב של GraphQL חלים על ISP ברמת השדה.השמצה מגדירה סוגים נפרדים ושאילתות עבור חששות שונים, ולקוחות יכולים לבקש רק את השדות שהם צריכים.coms כמו FLT:0Apollo פדרציהFLT:1 לקחת את זה הלאה על ידי גרף משותף, כל אחד מהם הוא חייב להיות מחובר מיקרו-מיקרו-שירות אחראי.
מיקרו-שירותים ו-Bounded Contexts
באדריכלות מיקרו-שירות, כל שירות חושף את ממשק משלו (API) שירות טיפול באימות המשתמש אינו צריך לדעת על עדכוני מלאי.על ידי שמירה על שירותים קטנים וממוקדים, אתה באופן טבעי לדבוק ב- ISP. על פי סעיף של מרטין Fowler על microservicesFLT:1, קידוד זה הוא מפתח לפרוסטיביות עצמאית והיקף.
SDK ועיצוב הספרייה
כאשר אתה מספק ללקוח SDK עבור ה- API שלך, ליישם את ISP בממשק הציבורי של הספרייה.לדוגמה, במקום מחלקה מרכזית אחת של 'ApiClient' עם מאות שיטות, להציע שיעורים מיוחדים כמו 'סדר', 'מוצרים קלים', ו'CustomersClient'.זה בדיוק מה ש-FLT:0AWS for JavaScriptFLTir, עושה כל אחד מהם שירות משלו.
מלכודות נפוצות וכיצד להימנע מהם
Over-Segation
הליכה מדי יכולה ליצור שפע של ממשקים זעירים מבלבלים לנווט ולתחזק.המטרה היא לא להיות ממשק אחד לכל שיטה, אלא כדי ליצור פעולות הקשורות באופן הגיוני שמשנות יחד.כלל טוב של אצבע: אם שני פעולות תמיד בשימוש יחד על ידי אותו לקוח, הם כנראה שייכים באותו ממשק.
גנטיקה מוקדמת
אל תפעילו ממשקים יותר מדי לפני שאתם מבינים את צרכי הלקוח.התחל עם ממשק קטן יותר, ורק תפיצו אותו כאשר אתם רואים ראיות קונקרטיות של תפקידים שונים של לקוחות או שינוי לחץ מאוחר יותר מקובל – במיוחד אם יש לכם אסטרטגיות לגרסה במקום.
התעלמות מ-Backward Compatibility
כאשר אתה מחלק ממשק קיים, לקוחות קיימים עשויים לשבור אם הם היו תלויים בחוזה הישן.תמיד לדחות בהדרגה.עבור REST, אתה יכול לגירסה נקודות הקצה שלך (למשל, '/v1/orders', '/v2/orders/read') עבור ממשקים פנימיים, תבניות שימוש כדי לגשר על חוזים ישנים וחדשים.
כלי ותיעוד מעל הראש
ממשקים נוספים מתכוונים ליותר תיעוד. להשקיע בכלים טובים של תיעוד API (כמו OpenAPI/Swagger או GraphQL Introspection) ולהבטיח שכל ממשק מתואר בבירור.המאמץ משלם באמון מפתח ואימוץ.
ISP ועקרונות SOLID אחרים
עקרון אחריות יחיד (SRP)
ISP באופן טבעי מתאים עם SRP. SRP אומר מודול צריך סיבה אחת לשנות.ISP מבטיח כי ממשק יש אחריות אחת - משרת תפקיד לקוח אחד. כאשר אתה עוקב אחר SRP ברמת המודול, לעתים קרובות בסופו של דבר עם ממשקים שכבר נחקרו.
Liskov Substitution Principle (LSP)
ISP אינו סותר את LSP. למעשה, ממשקים קטנים מקלים על יצירת יישום משנה.אם לממשק יש רק שתי שיטות, כל יישום אשר ממלא את השיטות הללו יכול להיות משולף בביטחון. ממשקי שומן לעתים קרובות לפתות מפתחים לזרוק שיטות לא מוגדרות (למשל, זריקת "NotImplementedException"), אשר מפרה את LSP.
Open/Closed Principle (OCP)
ממשקים ייעודיים תומכים ב- OCP כי אתה יכול להוסיף התנהגות חדשה על ידי יצירת ממשקים חדשים ולא לשנות את הקיימים.לדוגמה, הוספת פעולה אצווה אינה דורשת שינוי ממשקי הקריאה / הטלוט הקיימים - אתה יוצר ממשק חדש "באצ'ופר" שלקוח יכול לבחור ליישם.
הסתברות להורדת Principle (DIP)
ISP עובד יד ביד עם DIP: מופשטים (פניות) לא צריכים להיות תלויים בפרטים; פרטים צריכים להיות תלויים בהפשטות. כאשר הפשטות הללו הן מאוד כפייתיות ומפוכחות, אתה משיג גמישות מקסימלית בתלויים מתפתלים.
בדיקת API עם ISP בראש
החלת בדיקות ISP בדרגות מרובות:
- (FLT:0) בדיקות: 1 (FLT) 1 כל ממשק קטן ניתן ללעג בקלות.מבחן ללקוח לקריאה בלבד צריך רק ללעג לממשק הקורא, לא לכל ממשק ה-AP.
- (ב) בדיקות:0 (בקיצור: 1) ניתן לבחון נקודות קצה בבידוד.
- (FLT:0) בדיקות בדיקה: 1FLT 1 עם ממשקים צרים, בדיקות חוזים (למשל, באמצעות פצ'ט) הופכות ממוקדות יותר.כל עסקה של הצרכנים מכסה רק את האינטראקציות שהיא משתמשת, צמצום הסבירות של חיובי כוזב.
- (ב) מבחנים:0) תועדו: 1FLT:1 , כלומר, ניתן למיין נתיבי כתיבה, כדי לדמות את דפוסי השימוש בעולם האמיתי בצורה מדויקת יותר.
צמצום ההשפעה של ISP
איך יודעים אם עיצוב ה- API שלכם הוא מתוחזק היטב?חפש את האינדיקטורים האלה:
- "Fan-out" נמוך - שילוב לקוחות טיפוסי נוגע רק במספר נקודות קצה או ממשקים.
- שינויים נדירים בממשקים משותפים – אם ממשק משתנה לעתים קרובות מסיבות שאינן קשורות ללקוח העיקרי שלו, הוא כנראה רחב מדי.
- רק שיטות רחוקות - אם ה- API שלך מצטבר הרבה "@deprecated" שהן שאריות מורשת מממשקי שומן, הפרדה ההפרדה הייתה חלשה.
- זמן קצר להצגת מפתחים חדשים - ממשק API צר קל יותר ללמוד.
מסקנה
עקרון ה- Interface Segregation הוא לא רק מדריך אקדמי - זה כלי מעשי לבניית API שעומד במבחן הזמן.על ידי יצירת ממשקים קטנים, ספציפיים לתפקיד, אתה להפחית את ההפיכה, לשפר את חוויית המפתח, ולקבל את המערכת שלך יותר גמישה כדי לשנות.אם אתה מעצב נקודות קצה, GraphQLsche, SDK או, שואל "האם הלקוח שלך באמת צריך החלטות אדריכליות יותר?"
זכור, ISP אינו על כללים נוקשים אלא על כוונה.התחל עם נקודת מבט ממוקדת לקוח, הוא מבוסס על דפוסי שימוש אמיתיים, ולא לפחד לספק ממשקים כפי שהבנה שלך גדלה.התוצאה תהיה API שמפתחים אוהבים לעבוד איתו, אחד שיכול להתפתח ללא שבירת העולם.
לקריאה נוספת, לחקור את המאמר של ISP על ויקיפדיה ibph 1:1 ו- (FLT:2 רוברט C. Martin כתביו של רוברט C. Martin על SOLIDveFLT 3: משאבים אלה מספקים עומק נוסף על האופן שבו ISP מתייחס לירויים עיצוביים אחרים.