יום שישי, 4 בנובמבר 2011

RESTful Services - שירותי הרשת של המחר, החל מאתמול (1)

פוסט ראשון מתוך שניים. את ההמשך אפשר למצוא כאן.

REST הוא עוד באזז של השנים האחרונות: חברות אינטרנט רבות אימצו אותו, ספרים רבים נכתבו, גוגל יצרה וריאציה משלה בשם GDATA ומנסה להפוך אותו לסטנדרט. מייקרוסופט מצידה הגדירה אלטרנטיבה בשם [ODATA[1.

על מה כל המהומה?? - אנסה לענות במאמר זה.

מהו בעצם REST?
טוב, קחו נשימה עמוקה: REST הוא סגנון ארכיטקטוני (Architectural Style) ממש כמו Pipes & Filters, Layered Architecture או (SOA (Service Oriented Architecture.
סגנון ארכיטקטוני הוא לא ארכיטקטורה, אבל אם אתם יודעים מהו הסגנון הארכיטקטוני של מערכת (וגם הסגנון הזה נשמר לאורך הפיתוח) - תוכלו לדעת דיי הרבה על איך המערכת נראית ומה העקרונות שעומדים בבסיסה. ממש כמו שאם אתם הולכים לראות מבנה שאתם יודעים שהוא בסגנון גותי, סיני או ערבי - תדעו פחות או יותר למה לצפות.

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

REST הוא סט חוקים שמערכת יכולה לבחור ולאמץ. ב High Level הוא אומר שני דברים עיקריים:
  • תיאור ממשק המערכת כעולם של Entities (כ"א instance של אובייקט) כבעל מזהה (URL) ייחודי, דרכו ניתן לבצע פעולות. ממערכות כאלו נקראות Resource-Based Distributed System - שכל entity הוא כאילו משאב מסמך עצמאי עליו עושים פעולות[2].
  • הצמדות מדויקת לפרוטוקול HTTP - פרוטוקול שיש בו הרבה חוכמה שאנו נוטים לפספס.
ה API שנחשף החוצה, הוא התוצר - לא העיקר.


איך אני יודע אם אני משתמש ב REST
  • מספר רב של מתכנתים משתמש ב REST מבלי להבין את העקרונות (המעניינים) העומדים מאחוריו.
  • מספר רב של מתכנתים מאמין שהוא מפתח REST - וטועה. (נו, בסדר. זה משהו נחמד להתגאות בו ולספר לחבר'ה - אני יכול להבין)
  • נראה שרק חלק קטן מהאנשים מבין את REST לעומק. אני מקווה בפוסט זה לשפר את המצב במעט.
על מנת להשתמש ב REST API (נקרא גם RESTful Service) לא צריך לדעת כמעט שום דבר: פשוט פותחים connection של HTTP, שולחים פרמטרים ע"פ התיעוד של ה API ומקבלים תשובה בפורמט שתואר.
מצד אחד קצת חבל שכמעט כל מי שמשתמש ב REST לא מודע לעקרונותיו היפים, אבל מצד שני: היי - זה דבר נהדר! הכמסה (Encapsulation) במיטבה! אל תסבכו את הצרכן שלכם בידע מיותר.

אז...הדרך הנפוצה לדעת אם אתם צורכים ב REST הוא לקרוא האם בתיעוד כתוב "REST" ולקוות שמי שכתב את התיעוד מבין על מה הוא מדבר : )

אם אתם כותבים מערכת REST, יש הרבה מה לדעת - המשיכו לקרוא.

קצת היסטוריה
תחום האינטגרציה של מערכות ארגוניות (EAI - Enterprise Application Integration) הוא תחום מסובך ויקר במיוחד. רכשת מערכת כספים מספק א' ומערכת ניהול קשרי לקוחות מספק ב' - על מנת לנצל את היתרון שהמערכות ממוחשבות וניתן להצליב בניהן נתונים, אתם צריכים לגרום למערכות לדבר אחת עם השנייה. בגלל שהמערכות מדברות בשפה (Conceptual Model) שונה ובגלל שהארכיטקטורות שלהן שונות - המאמץ הוא אדיר. כשאנחנו נזכרים בסיפורים בהם משרדי ממשלה לא מצליחים להצליב נתונים (ביטוח לאומי ומס הכנסה, או ארגוני ביון אמריקאים לפני שנת 2001) אנו נוטים לחשוב שזהו מצב של חלם, אבל בפועל עלות האינטגרציה היא אדירה ולעתים קרובות עולה על מחיר המערכות עצמן[3].

כך נראה פרוייקט EAI של ארגון בגודל בינוני

בתחילת שנות האלפיים חברו כמה חברות בראשן BEA, Microsoft, IBM ו SAP ליצור סטנדרט בתעשייה שיקל על פעולות האינטגרציה של מערכות. תקן זה ידוע כ "Web Services" הכולל Stack של פרוטוקולים שהעיקריים שבהם הם: SOAP, WSDL, UDDI ו XML (שהיה כבר קיים אך אומץ ע"י הסטנדרט). תוך כדי התפתחה מאוד ההתעסקות ב (Service Oriented Architecture (SOA. העיקרון אינו חדש: זה תיאור של מערכת מבוססת services ו מבני נתונים המחזיקים את המידע העובר בין ה services, ממש כמו שתכנתנו פעם בפאסקל או C. גם היום חלק גדול ממערכות ה .NET וה Java בנויות כך, לעתים מתוך החלטה, לעתים "כי פשוט יצא ככה". החידוש ב SOA היה הידע שנצבר והתפתח עבור אותה פרדיגמה במערכת מבוזרת.

יוצרי ה Web Services היו זקוקים לשם מפוצץ ("SOA") וצבא של יועצים-מומחים בכדי לשכנע את השוק לאמץ את גישתם. על פני השטח זה נראה כמו וויתור על פרדיגמת ה Object-Oriented (אותה, אותם יועצים ממש, מכרו כמה שנים לפני כן כ "חובה לכל ארגון") וחזרה לסגנון התכנות הפרוצדורלי (ברמת המערכת) שהיה שם קודם לכן. הם ניסו לשכנע שזו לא התדרדרות אחורה - אלא התקדמות קדימה. האמת - הם צדקו [4].

עם השנים (כמה שנים בודדות, לא יותר) תקן ה Web Services הסתבך לעשרות תקני משנה, הידועים כ WS-* (כוכבית = wildcard כמו WS-RPC, WS-Security וכו') שניסו לפתור עוד ועוד היבטים של אינטגרציה בין מערכות תוך כדי שהם נהיים מורכבים יותר ויותר לשימוש. קשה היה לאדם בודד להכיר את כל התקנים ובטח לא להתמצא בהם. בעיה נוספת הייתה performance: בגלל שהתקן מאוד כללי (בנוי לקשר בין מערכות מספקים שונים, הכתובים בשפות תכנות שונות ובין גרסאות שונות) ובגלל שהוא מבוסס על קבצי XML גדולים, פורמט המרבה במילים (verbose) - תקשורת מבוססת Web Services הייתה צוואר בקבוק גם של הרשת, אבל בעיקר של צריכת זיכרון (בשל ה parsing של קבצי xml ענקיים). עניין זה היה מטרד למערכות ארגוניות, ומכת מוות למערכות אינטרנט High Scale.

חברות האינטרנט הקטנות והיעילות יצאו למלחמה רבתי: "REST נגד SOA" - ראה [5]
הם הציגו את REST כאלטרנטיבה פשוטה, מהירה ונוחה למתכנת לייצר Web Services. הם גם נתנו לשירותים אלו שם מפוצץ משלהם: "RESTful Services". אני זוכר שהייתי בכנס QCON בלונדון בשנת 2008, ורבים מה sessions היו על נושאים ב REST או ב SOA (למשל, אני זוכר session שנקרא "REST eye for a SOA guy"). כל פעם באו אנשי המחנה השני, קראו קריאות ביניים והפריעו למרצה ב Session. מהר מאוד למדתי להדיר רגלי מכל Session באחד משני הנושאים הללו.

מכיוון שפוסט זה עוסק ב REST ולא ב Web Services אתם יכולים להסיק, בצדק, ש REST ניצחה במלחמה. השימוש ב Web Services הצטמצם משמעותית ונותר בעיקר בנישה של מערכות שונות של ספקים שונים. אפילו החברות אשר יזמו וקידמו ללא ליאות את הסטנדרטים (עבדתי ב SAP - אני יודע) הוציאו הנחיות פנימיות לצמצם שימוש ב Web Services למינימום ההכרחי.

הפשטות ניצחה את ה Coverage.


הבנת ההבדל בין Web Service ל REST
גם REST וגם Web Service הם אמצעי תקשורת בין מערכות שונות המבוססים על XML העובר על [HTTP[6 - היכן ההבדל הגדול?

עדכון: תודה לארנון רותם-גל-עוז שהאיר את עיני לכך ש REST אינו coupled ל HTTP ואותם עקרונות יכולים להיות  מיושמים על גבי פרוטוקולים אחרים (אישית, לא נתקלתי בכזה מימוש).

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

getOrderDetails()
updateOrder()
Subscribe()
cancelSubscription()
findMatchingOrder()
listOrderProviders()


פונקציות כמו ()Subscribe או ()ListOrderProviders אינן קשורות בדיוק להזמנה, הן בתחום. את ה interface השירות חושף בעזרת XML שנקרא WSDL כך שמי שצורך אותו יוכל בקלות לבצע import ל IDE אשר ייצר proxy לוקלי לקריאה לשירות כאילו מדובר באובייקט מקומי. Visual Studio, כבר מימיו הראשונים של .NET עושה זאת בצורה נהדרת.
כאשר מתבצעת קריאה ל Web Service בפועל, נוצר XML עם הפרמטרים הרלוונטיים. XML זה נעטף ב XML נוסף הנקרא Envelope של פרוטוקול ה SOAP (ה envelope מוסיף נתונים העוזרים ל cross platform interoperability אך ייתכן ויהיה גדול משמעותית מההודעה עצמה). אם ה Web Service תומך או דורש שימוש בכל מיני שירותים נלווים (WS-* למיניהם) יש להתייחס אליהם וייתכן שהם יוסיפו תוכן או ישנו את צורת ההתקשרות.


RESTful Web Services
REST, כפי שאמרנו, מתאר Resource-Based Distributed System. הגישה היא ל resource (או האובייקט) עצמו ולא לשירות. לרוב מדובר על המון משאבים (הממופים כ"א ב URL), אשר כל כ"א סט מצומצם וקבוע של פעולות המוגדרות  בפרוטוקול HTTP.

על מנת לקרוא את פרטי ההזמנה אבצע קריאת HTTP GET ל URL:

http://example.com/orders/2009/10/776654

על מנת לעדכן את ההזמנה אבצע קריאת HTTP PUT ל URL:

http://example.com/orders/2009/10/776654

את נערכים שאני רוצה לעדכן אשלח כ Post Parameter בפורמט XML או JSON הכולל את הערכים הרלוונטיים.
על מנת לבצע שאילתה על כל ההזמנות בשנת 2009 של לקוח AMEX אני אבצע קריאת HTTP GET ל URL:

http://example.com/orders?year=2009&customer=AMEX

האובייקט הוא orders, אני מבצע קריאה ושולח פרמטרים ל Query בשם year ו customer.
כמובן שאני לא יכול לשלוח מה שבא לי - רק מה שהוגדר ע"י ה שAPI ומתועד ב API Documentation.

ועל מנת לבצע שאילתה של listOrderProviders נגשים ל"אובייקט" ה OrderProviders, כמובן:

http://example.com/orderproviders?orderid=776654

אם ביצעתי קריאת GET להזמנה שאינה קיימת אקבל כנראה שגיאת HTTP 404, המוגדר בפרוטוקול HTTP כ "Not Found". אם ביצעתי קריאת POST (הוספת ערך חדש) אצפה באופן טבעי לתשובת HTTP 201 המוגדרת בפרוטוקול HTTP כ "Created". עבור ביצוע אסינכרוני אצפה ל 202 "Accepted" וכו'

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

קשה לי לתאר במילים כמה פרוטוקול REST פשוט יחסית לפרוטוקול WS-*. אחד הטיעונים נגדו היה שזהו Hack שלא יחזיק מים במערכות גדולות ומורכבות (טעות). פעם בקורס על Web Services ב SAP ישבנו שעתיים רק לסקור את סוגי השירותים השונים של WS-* וזה היה על קצה המזלג.

חשוב להבין ש RESTful API (כלומר, מימוש נכון של REST) משפיע רבות על המבנה הפנימי של המערכת. עצם העובדה שכל instance של אובייקט הוא נגיש החוצה וניתן לבצע עליו סט סגור של פעולות הוא עיקרון שיצליח אם מערכת בנויה בצורה X אך יכול להיכשל אם מערכת בנויה בצורה Y.

המשמעות של הוספת RESTful API למערכת קיימת שאינה בנויה בצורה REST-friendly היא לרוב להוסיף שכבת Adapting עשירה או לא להצליח להנות בפועל מיתרונות ה REST. ייתכן וכל מה שאתם מחפשים הוא לחשוף API בצורה שהמשתמשים רגילים (REST like) ולכן יתרונות ה REST האחרים הם לא חשובים. לגיטימי.

הקשר בין REST לפרוטוקול ה HTTP וארכיטקטורה של Resource-Based Distributed System אינו מקרי.
בפוסט ההמשך ארחיב על נושאים אלו יותר לעומק.



[1] Open Data. מכיוון שהצלחה נראתה כיעד אסטרטגי מהותי - היא שיחקה עם גוגל במגרש שלה, פתחה את התקן כ Open Source ושחררה ספריות התומכות ב .NET כמובן, אך גם PHP, Java ו JavaScript.

[2] היסטורית מקובל לחלק מערכות מבוזרות ל 4 סוגים:
  • Object-Based Systems: מערכות שמאפשרות לגשת מרחוק ולהפעיל אובייקטים עשירים בפרדיגמת Object-Oriented. דוגמאות הן Corba, DCOM או EJB כאשר עובדים עם Remote Interface.
  • Distributed Database / Storage System - כאן נכנסים כל מערכות ה NoSQL שתיארתי בפוסט על Big Data או מערכות קבצים מבוזרות נוסח Gopher, WebDAV או HDFS ו GFS המודרניים.
  • Distributed Coordination-Based Systems: מערכות תיאום מבוזר כמו Rendezvous או Jini של ג'אווה שנכשל ונולד מחדש כ Apache River. דוגמה מודרנית יכולה להיות פרוטוקול Gossip או מערכות peer 2 peer.
  • ומה שחשוב לפוסט זה: מערכות Resource-Based (לעתים נקראים גם "Document-Based") מבוזרות אשר ניגשים ל Resources ("מסמכים") אחד אחד לצורך פעולות קריאה, כתיבה וכו'. דוגמה אחת: האינטרנט (מסמכי HTML). דוגמה שנייה: מערכות REST.

[3] זה הסיפור העיקרי עליו מבוססת מכירת מערכות ERP של חברות כמו SAP או Oracle: "אין לנו את ה CRM הטוב ביותר או ה SCM הטוב ביותר - אבל אתה קונה את האינטגרציה built-in".

[4] שנים רבות Object Oriented Programming נחשב לשם נרדף לקדמה ומקצועיות, אבל בפועל הוא לא היה Silver Bullet - כלומר לא הביא לשיפור חד משמעי בעולם התוכנה. לתכנות פרוצדורלי יש הרבה יתרונות ונראה שיש לו עוד מקום של כבוד בעולם התוכנה בשנים הבאות. כמובן שעדיף להבין את היתרונות והחסרונות המעשיים של כל גישה ולבחור בחירה מודעת. סימן אחד לכוחה של הפרדיגמה הפרוצדורלית היא שהרבה מאוד פרויקטים שניסו לייצר מודל OO כשלו וגמרו עם מודל פרוצדורלי. כלומר: OO הוא קשה למימוש, פרוצדורלי הוא קל. חישבו על כך - זהו יתרון משמעותי.
תכנון מונחה עצמים Object Oriented Design, לעומת זאת, הוכיח את עצמו יפה והוא מוצלח משמעותית מכל מיני פרדיגמות עתיקות כמו DFD (השם ירחם!) או ERD שנהגו להשתמש בהם בשנות השמונים (או בסוף שנות התשעים באקדמיה - אותה תקופה בה למדתי את התואר הראשון). יהיה זכרם ברוך.

[5] SOA היא ארכיטקטורה טובה, הם בעצם התכוונו לצאת נגד Web Services. עקרונית REST הוא סוג של SOA.

[6] REST לא מגדיר מה פורמט ההודעה, XML נפוץ מאוד וכך גם JSON ואפשר גם להשתמש בפורמט אחר כלשהו.

14 תגובות:

  1. לו היית בכל זאת משקיע קצת בתאוריה ולמשל קורא את הדוקטורט של פילדינג שבו הוא הגדיר את REST - http://www.ics.uci.edu/~fielding/pubs/dissertation/top.htm
    אז סביר להניח שלא היית מגדיר אותו כפי שהגדרת
    לREST יש 4 עקרונות
    1. זיהוי של resources (מה שבhttp הוא uri)
    2. שינוי resources ע"י representations
    3. הודעות שמתארות את עצמן
    4. שימוש בהיפרמדיה כמנוע לשינוי מצב האפליקציה

    כמובן שניתן לבנות מערכות rest על http אבל זו לא הדרך היחידה ומה שיותר חשוב יש להן השפעה יותר מעמיקה על עיצוב ההודעות והדרך לעבור בין מצבים וכו ממה שתארת
    ארנון

    השבמחק
  2. תודה על ההערה המדוקדקת.
    מה שאני מנסה לעשות הוא להפשיט נושא מורכב מהפורמליסטיקה ולתת כמה תובנות משמעותיות שקל להפוך למעשים "מחר בבוקר".

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

    אם יש לך חומר ענייני וקל לצריכה (דוקטורט פורמאלי בן עשרות עמודים זו לא דוגמא טובה) - אשמח אם תגיב ותקשר :)

    השבמחק
  3. אם אתה מפשט נושא מורכב לרמה שבה עקרונות מרכזיים שלו חסרים אתה בדיוק גורם למה שהגדרת: "מספר רב של מתכנתים מאמין שהוא מפתח REST - וטועה"
    גם בדוקטורט אפשר להתרכז בפרק 5 שמדבר תכלס על rest
    יש גם את המאמר של וובר ושות : http://www.infoq.com/articles/webber-rest-workflow
    ויש גם את המצגת שלי http://rgoarchitects.bit.ly/6XRPam שאני רוצה להאמין שמציגה את העיקרים :)

    ארנון

    השבמחק
  4. ארנון שלום, המצגת שלך לא מובנת, היא מציגה את העניין בצורה מאוד כללית (מאוד מאוד, תמונות בעיקר). לאור זאת הביקורת שלך על הבלוג של ליאור היא קטנונית מדי, ולא במקום.
    משהוא שכותב מאמר שכזה ראוי להערכה, וזכה להערכה שלי.

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

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

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

    השבמחק
    תשובות
    1. תודה על ההסבר :)

      מחק
  7. ותודה שכתבת בעברית :)
    באנגלית כל המאמרים האלה נראים סינית

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

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

    השבמחק
  9. היי ליאור. לא הבנתי למה OOD מתחרה ב DFD או ב ERD?
    אני סטודנט שנה ג' וזה חלק ממה שלמדנו ועד ההערה שלך הרגע לא חשבתי שזה מיושן. (טוב אני לא בתעשייה כרגע) ובכל אופן אשמח להמלצה על כיוונים איפה אפשר לקרוא על ה - OOD

    השבמחק
    תשובות
    1. היי ישראל,

      בשתים עשרה שנות הקריירה שלי לא נתקלתי במישהו שעבד עם DFD, ולא ראיתי שום אזכור ל DFD למרות כנסים רבים, עשרות ספרים שקראתי, ומאות מאמרים שקראתי בתחום (אני מעריך).
      אם אני מזכיר ERD (שהוא עוד יחסית רלוונטי) - אז מי שמכיר הם לרוב חבר'ה ותיקים, שעבורם זו סוג של נוסטלגיה. עדיין מתארים היום סכמות של בסיס נתונים כמובן - אך עושים זאת לרוב בצורה פחות פורמאלית. האמת שבשנה האחרונה ראיתי מישהו ששרטט ERD :)

      אני לא טוען ש OOD היא הדרך הנכונה לעשות דברים. זו רק עוד טכניקה. המקור הפופולארי שאני מכיר ללמידת OOD הוא הספר של קרייג לרמן (http://goo.gl/mL9Lw), אבל גם OOD כיום הוא "קצת מיושן". מה עושים במקום? Lean Startup (הנה הספר: http://goo.gl/i0aj1J) הוא ה Cutting edge. יש כמובן מגוון כלים וטכניקות המנסים לענות לשאלה האלמותית "איזה תוכנה עלי לכתוב?".

      מקווה שעזרתי,
      ליאור

      מחק
    2. אשלים תשובה לשאלה הראשונה שלך: ERD ו DFD הם תרשימים שיוצרים כחלק מתהליך של ניתוח מערכת - הבנת ומיפוי הצרכים העסקיים והגדרת התוכנה שתספק אותם. OOD הוא תהליך מקביל שעושה ממש את זה.

      כלומר: הם לא מקבילים בדיוק, אך לרוב אדם יעבוד באחד מהכלים ולא בשלושתם - על מנת להשיג מטרות דומות.

      מחק
  10. שלום, יש לי מערכת מבוססת Cloud, כל הservices (Radius, mongoDB, WEB SERVER, Rest API) יושבים בענן. דרך ממשק משתמש הקליינט מתחבר למערכת ואחרי פעולת אוטנטיקציה וקבלת Credentials נוצר הקליינט במערכת. אשמח לדעת מה הבקשה ליצירת קליינט בDB בRestful?

    השבמחק