Site icon בלוג ארכיטקטורת תוכנה

על המגבלות של REST – בשירות מערכות ווב בנות-זמננו

כבר כתבתי על REST בבלוג: ב 2011 (בהרבה התלהבות) וגם ב 2016 (במתינות) – מה ששיקף תהליך אישי של התלהבות רבה מ REST, והתפכחות לאורך הזמן.

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

מעולה, לחלוטין הייתי שמח לראות יותר דיפ דייב בנושאים שסקרת פה

הובילו אותי לפוסט הנוכחי, ולהציג היבטים נוספים של תקשורת ו REST – והאופן שאני מציג אותם כיום.

על אלו מגבלות אנחנו מדברים? הרי REST הוא כמעט-מושלם, לא?

למי שלא זוכר / לא היה בתעשייה בשנות ה-2000 אזכיר בקצרה את ההיסטוריה:
בתחילת שנות ה-2000, כאשר התברר לתעשיית התוכנה שמערכות תוכנה הולכות ונעשות מורכבות יותר, ויותר – ולכן רבות מהן הופכות למערכות מבוזרות (יותר משרת אחד) – ומכאן צמח רעיון ה Service-Oriented-Architecture (בקיצור: SOA) לארגון של מערכות מבוזרות שכאלו. מייקרוסופט הציעה את פרוטוקול ה SOAP (לשעבר XML-RPC) כבסיס לתקשורת בסוג הארכיטקטורה הזו, מה שהתקבל במהרה ע"י יבמ, ושאר חברותיה.

החברות שהובילו אז את התעשייה (IBM, HPE, Microsoft, וכו') קידמו את רעיונות ה-SOA לכדי מציאות, ועבדו על Suite של פרוטוקולים בשם *-WS שיפתרו את כל הבעיות התקשורת והאינטגרציה של מערכות Enterprise (מה שהיה מעניין באותה תקופה).

סט הפרוטוקולים המרכיבים את *-WS

בחבילת הפרוטוקולים של *-WS היה כמעט הכל, לקחו בחשבון כמעט כל צורך של Enterprise Software, מלבד אחד חשוב מאוד: פשטות.

לא כולם אהבו את SOAP ו *-WS, אחד מהם היה רוי פילדינג אחד ממגדירי התקן של HTTP. בעיניו – HTTP היה "הפרוטוקול של האינטרנט" ועל אף ש HTTP נועד להגשת "דפי ווב", הוא חשב שפרוטוקול אפליקטיבי צריך להשתלב בצורה הרמונית (אולי "טבעית") עם HTTP וה Web Standards הקיימים, ולא להתעלם ולהחליף אותם. זו הייתה מן גישה מוקדמת של "קיומיות וובית" – שהייתה חדשה ומרעננת באותה התקופה. היום קוראים לזה "Web-native".

פילדינג פרסם באותה תקופה עבודת דוקטורט, שבה פרק מס' 5 (המפורסם!) הציג סגנון ארכיטקטוני בשם Representational State Transfer (בקיצור: REST) למערכות ווב, ארכיטקטורה שמשתלבת באופן מאוד טבעי עם ה World Wide Web ו HTTP.

הסגנון הארכיטקטוני של REST הוא בעל התאמה מצוינת למערכות פורומים, או אתרי Wiki – אך למערכות ווב מורכבות של ימנו, היא לא באמת רלוונטית. אני בטוח שלכמה קוראים המילים הללו כואבות, ויש עדיין כאלו שמנסים ליישם ארכיטקטורת REST במערכות תוכנה מודרניות. אני אישית השתכנעתי לגמרי בחוסר-הרלוונטיות של REST כסגנון ארכיטקטוני לרוב מערכות הווב המורכבות והמודרניות.

תוצר לוואי של "ארכיטקטורת ה REST", כפי שהוגדרה בעבודת הדוקטורט של פילדינג, היה צורת התקשורת בין חלקי המערכת, מה שנקרא כיום RESTful APIs. כלומר: צורת תקשורת של העברת הודעות JSON (במקור: XML) על גבי HTTP תוך השתלבות הרמונית באופיו והתנהגותו של HTTP והווב. ל HTTP יש מנגנונים כגון Caches, ו resource naming (להלן ה URL) הנכונים גם לתקשורת אפליקטיבית – שאם משתמשים ב HTTP, לא צריך לפתח מחדש. העולם מלא בכלים (למשל: דפדפן, Firewalls, Postman, swagger) שעובדים כבר עם HTTP, והמבנים של HTTP (כלומר: URL, Status Codes, Methods, Headers, Cookies) – מוכרים היטב* בתעשייה, ומקלים על אימוץ הטכנולוגיה.


* האמירה ש"כולם מכירים HTTP" היא סופר-מקובלת בתעשייה, אבל פה אני צריך להשתעל קצת – ולהתוודות שהיא לא לגמרי נכונה. גם כיום, בעידן הידע, ה Geektime, ושנים לאחר ש RESTful APIs הפכו לסטנדרט הלא-מעורער של התעשייה – אני נתקל בחוסרים גדולים של מהנדסי תוכנה בהבנה בסיסית של פרוטוקול ה HTTP. נכון יותר לומר ש HTTP מתועד היטב ויש עליו אינסוף חומר ו References – ולכן הוא נגיש יותר מפרוטוקולים proprietary אחרים.

חזרה לתחילת שנות ה-2000: חברות האינטרנט שאז היו עוד צעירות: אמזון, יאהו, גוגל ועוד – אימצו בהתלהבות את REST (או ליתר דיוק: את ה RESTFul APIs) ושינו את מהלך ההיסטוריה. SOA, עם כל התכנון ההנדסי העמוק שנעשה מסביבו, ולמרות הגיבוי של חברות הענק – נקבר בעמודי ההיסטוריה, ו REST הפך לדרך התקשורת הנפוצה והמקובלת במערכות ווב בעשור וחצי האחרונים.

להיכן ממשיכים מכאן?

REST איננו תקן (אלא פרק בעבודת דוקטורט) והפרשנות ל RESTFul APIs אף יותר מזה – היא פרשנות, שכל אחד יכול לקחת למקום שונה. עם הזמן צצה הביקורת על "גנבי-הדעת" שפשוט מעבירים XML על גבי HTTP וקוראים למה שעשו "RESTful API" – מבלי באמת לכבד את פרוטוקול ה HTTP ו/או להשתלב בעקרונות הווב המקובלים (resources, openess, linking). מודל הביקורת שתפס יותר מכל להערכת "יישום RESTful APIs" הוא Richardson's Maturity Model (בקיצור RMM):

הפסים שאתם רואים בשכבה הנמוכה הם בוץ, רפש – שדובקים בכל מי שמסתפק ב "XML/JSON over HTTP" ועוד קורא לזה REST.
גם אני, כשהייתי עוד REST Evangelist – כעסתי על כל מי שנוהג כך. מה, אין כבוד?

ע"פ מודל ה RMM, לשלוח XML או JSON על גבי HTTP הוא נקודות האפס הבסיסית ביותר (והמוערכת הכי פחות). משם אפשר להתקדם לעיצוב "נכון" של URLs, שימוש "נכון" ב HTTP Verbs, ועד הגביע הקדוש של Hypermedia transformations. השתלבות המערכת עם "טבע ה HTTP והווב".

גם בחיים האמיתיים, אפשר לחתור להרמוניה מלאה עם הטבע: להפסיק להשתמש בתוצרי התעשייה, לא לזהם – ולחיות רק ממה שהטבע הפראי מספק. בעוד שיש הרבה אידאל בגישה הזו – לא בטוח שזו צורת החיים האופטימלית לכולם. אולי אני רוצה סכין שיוצרה במפעל, שיקל על מלאכת ההישרדות? אולי בית וחומרי בידוד? כמה רחוק "נכון" ללכת עם רעיון ההשתלבות בטבע?

שאלה דומה היא שאלת ההשתלבות ב HTTP/Web ומידת ההצמדות לרעיון ה REST: יישום של RESTful APIs ברמה 3 לפי ה RMM אולי תעניק לכם חיים בעולם הבא בקרב "קהילת נאמני ה REST" – אך כנראה גם תתברר כעבודה הנדסית בינונית עד איומה, ברוב המקרים. למשל: רמה 3 טוענת שכל קריאה לשרת צריכה לבוא מתוך "גלישה טבעית בווב". באתר ווב אני מתחיל מאתר הבית – ובסדרה של קישורים מגיע לדף בו אני מעוניין. באופן דומה, הטענה היא ששרתים שמדברים זה מזה – צריכים להתקדם למטרה בצעדים. לא לשאול: "כמה כסף יש בחשבון של לקוח X?" אלא תמיד יש להתחיל בשאלה "מי אתה? אלו לקוחות יש לך? איזה מידע יש לכל לקוח? האא… ורק אז לשאול: אז כמה כסף יש בחשבון של לקוח X?".

אם יש לנו שרתים "קרובים" (אותה מערכת) שמתקשרים הרבה, ההבדל בין 4 קריאות (3 "נימוסים" + 1 תכל'ס) על כל בקשה מול קריאה בודדת (רק תכל'ס) – היא משמעותית. רק במקום עבודה אחד בחיים ראיתי יישום של Hypermedia transformations – ואולי עשינו HATEOAS, אבל סיבכנו מאוד את המערכת. ממש ברמת העוול / הטיפשות.

מכאן עולה השאלה המתבקשת: "כמה RESTFulness" כדאי לעשות? ואיך יודעים לאמוד מתי ההצמדות ל RESTfulness היא תורמת, ומתי היא כבר מזיקה?

אז מהן המגבלות העיקריות של RESTFul APIs?

אני יכול להמשיך לדבר/לכתוב על הנושא הזה על בלי דיי. עסקתי בו – מאות שעות לאורך שנים, ודנתי ודשתי בו עם אנשים שונים וגישות שונות. בכל זאת, אשתדל לקצר.

Hypermedia Transformations / HATEOAS – ברוב המקרים, מבחינה הנדסית – זה פשוט טירוף לשמו. יש להימנע – וחבל להמשיך ולעסוק בעניין.

HTTP Verbs הם שפה מגוונת ועשירה למערכות פורומים / Wikis – אך דלה ומוגבלת עבור מערכות ווב מודרניות ומורכבות. הנה ההגדרות מתוך וויקיפדיה:

והנה כמה מגבלות יום-יומיות ,שכנראה שכולנו נתקלים בהן:

הנה פרשנות אחת (ומקובלת) מתי להשתמש ב PUT ומתי ב POST ליצירת אובייקט. יש עוד כמה פרשנויות סבירות והגיוניות.
מישהו ריכז כאן דוגמאות וגישות ל versioning ב REST (והיד עוד נטויה). רק להדגים שהנושא אינו "סגור בטון" ומקובל על כולם באותו האופן.

אלו צרכים בסיסיים, שכנראה רוב מערכות הווב של ימנו זקוקות להם.
חשוב לציין ש HTTP/2 הוא כבר פרוטוקול בינארי, עם יכולות notifications, ואסינכרוניות (Pipeline/streams) – אך עדיין לא נתקלתי ב RESTful APIs שמשתלב ביכולות הללו בצורה הרמונית וטבעית.

סיכום

חזרנו והתבוננו ב REST בראייה מפוכחת, לא רק "REST זה טוב, SOA זה רע" – פזמון הפאנק של אמצע שנות ה-2000.

אני לא ממליץ לאף אחד לחזור ל *-WS או SOAP חלילה, הם כבר עתיקים ולא רלוונטיים. ייתכן ו RESTFul APIs זו הגדרה מספיק טובה לסט מצומצם של Public APIs של חברה (והרי ב Public API יש יתרון גדול בשימוש בתמות מוכרות), אך דיי ברור שלצורכי התקשורת הפנימיים של מערכת מורכבת / מיקרו-שירותים, RESTFul APIs היא גישה מוגבלת מדי ודלה בסמנטיקה – שחייבת הרחבה.

REST מעולם לא היה תקן, אף אחד לא מבאר אותו ומשפר אותו, ולא מתאים אותו לרוח התקופה. הוא הוצג בתחילת שנות ה 2000 – ועולם התוכנה השתנה מאז, ומאוד. אין תלונות.

לא ענינו על התשובה לשאלה: "כמה RESTFulness כדאי לעשות? ואיך יודעים לאמוד מתי ההצמדות ל RESTfulness היא תורמת, ומתי היא כבר מזיקה?" – אל אני מניח שכל ארגון תוכנה בימנו ש"מתבסס על REST" צריך לשאול את עצמו את השאלה הזו – ולהמציא תשובות.

יש ניסיונות כנים ומשמעותיים לנסות ו"לתקן" את REST (בצד התקשורת; צד הארכיטקטורה הוא מאוד ספציפי ומתאים רק למיעוט שבמיעוט שבמערכות) למשל JSON API או להיצמד ל Guidelines של מישהו שעשה עבודה משמעותית, למשל ה Microsoft RESTFul API Guidelines. פעם מישהו הציע לי לאמץ בארגון את JSON API ושללתי את זה על הסף ("כל ארגון יגדיר את מה שמתאים לו"). היום הייתי מתייחס לאופציה הזו ברצינות גדולה יותר. לא כ "תורה מסיני שתפתור הכל", אלא כדי לא להתחיל את תהליך ההגדרה הארגוני מאפס.

לא נכון לכעוס או להתאכזב מ RESTFul APIs כרעיון כללי כ"כ, לא מוגדר היטב, ופשטני. הפשטות הזו – פתרה בעיה גדולה לארגונים בשלב הצמיחה (גוגל, יאהו, ועשרות-אלפי סטאראט-אפים נוספים) ושירתה אותם היטב. הכלליות – התאימה ל"כולם" (כל אחד מצא שם משהו שדיבר אליו, בלי משהו גדול להתנגד אליו) ויצרה "רעיון" שמשך אחריו את כלל התעשייה – גם אם לא היה מדובר בתקן מדויק. רעיונות ה Web-Native חלחלו עמוק, והיום מהנדסים רבים כל-כך חותרים להשתלב עם הווב, במקום "להחליף את הקיים".

תנועות כגון Forget HTTP + הרצאה או HTTP Hell-no אולי מביעות הרבה תסכול מה"אכזבה" של REST בפועל – אך מנסות להציע גם חלופות ותיקון.

טכניקות כגון Polling, Long-Polling ו Webhooks הן דוגמאות פשוטות להרחבות טכניות פשוטות – המאפשרות עוד הרבה מרחב תמרון במקומות ש HTTP/REST מוגבל בהם ("client קורא ל server", וזהו). יש לי הסברים מפורטים על הטכניקות הללו – אניח לרגע שכל הקוראים מבינים אותן. כן גם משמרות את האופי של HTTP/REST כמעט ולחלוטין – זו רק הרחבה.

הפתיחות לאמץ אלמנטים של RPC בצורת העבודה של הארגון (להתגמש ב Resource modeling, להוסיף קודים של הארגון לכל תשובה, ו/או מבנה סטנדרטי של בקשה/תשובה לכלל המערכת) עשויים לשרת אתכם היטב, גם אם "קהילת נאמני ה REST" – ידיחו אתכם מחברות בארגון / חיי נצח / ההבטחה ל 70 מהנדסות תוכנה (טובות!) בעולם הבא.

(אם מישהו ישאל, JSON-RPC הוא פשטני ונאיבי מדי לטעמי, וגם אותו תאלצו מהר מאוד להרחיב ולהגדיר בעצמכם. RCP בינארי כמו Thrift או gRPC הוא אטקרטיבי לשיפור ביצועים / אמינות התקשורת – אך מהלך כבד מדי אם כל מה שאתם מחפשים הוא סמנטיקה וכללי עבודה טובים לבעיות מידול ה Endpoints במערכת שאינה very high scale, הפשטות הרי חשובה).

בקיצור: אני חושב שנכון להודות על מה שיש (RESTFul APIS, HTTP, או מה השאתם משתמשים) – אבל לא להניח שזה מספיק כדי ליצור תשתית תקשורת מספיקה לצורכי המערכת והארגון – בעיקר ככל שהמערכת מתפתחת והארגון גדל. הניחו שיהיה עליכם להגדיר שפה וכללים משלכם – שישרתו אתכם, וזה בסדר.

אם אתם עובדים ברמה של HTTP בצורה ניכרת (או ב RESTFul APIs או ב RPC כלשהו, למשל home-made) – חשוב ללמוד את התקן הפשוט והחשוב הזה, ולהבין אותו. אני רוצה להאמין שזה מאמץ קטן ומשתלם. יש את הפוסטים שלי (HTTP Basics + מבנה ה URL) אלו ואלו, יש את הרפרנס הנחמד הזה של for-get-HTTP – HTTP References שמצאתי במהלך כתיבת הפוסט – ונראה לי שאשתמש בו עוד בעתיד.

מחשבות, הערות, תוספות – יתקבלו בברכה!

Exit mobile version