2020-04-15

תכנון נכון של API

תכנון API הוא מלאכה עתיקה ולא-מוסדרת. כל מהנדסי-התוכנה מתכננים (או פשוט מיישמים) APIs. מחתימה של פונקציה, עד ל Public APIs בפרופיל גבוה ("Public APIs, like diamonds, are forever״).

אם הייתי קורא כזה פוסט, הייתי רוצה שלא יעסוק ב:
  • כללי ה REST. דיי נמאס! אחרי עשור ויותר, אפשר להניח שכל מפתח מכיר אותם היטב, או לפחות יש מספיק חומר סביר בווב (כולל הבלוג הזה) בכדי לכסות את הנושא לעייפה.
    • במקום העבודה הנוכחי שלי, ירדנו מ REST - לטובת Json over HTTP. זה היה לי קצת מוזר בהתחלה - אבל היום זה נראה לי כמו צעד נבון. אפרט קצת בסוף הפוסט.
  • GraphQL או Falcor = עוד באזז / טכניקה. כמו REST יש כאן שורה של כלים וכללים שאפשר ללמוד אותם - אבל האם זה באמת החלק החשוב ב APIs טובים יותר?!
  • כללים גנריים ובסיסיים ״צרו תעוד ל API״ , ״בדקו את ה API״, ״בחרו שמות טובים ל API״. אני מניח שאתם לא צריכים את הבלוג הזה בכדי למצוא את כללי היסוד של ההיגיון הבריא.

אז זהו. לא אעסוק בכל הנ״ל. הרשת גדולה - ואני אשאיר לאחרים לדוש בנושאים הנ״ל. עם כל החומר על ה API שיש ברשת (בעיקר: Rest, Rest, ו GraphQL) - נשארנו עם הרבה טכניקה, ומעט נשמה.

אם אתם גיקים אמיתיים - אתם בוודאי מאמינים בלב שלם שהטכניקה מספיקה. ש < שם של סגנון טכני של APIs [א] > הוא הפתרון השלם והטוב ביותר. אם תקפידו על הכללים הטכניים - יהיה לכם API מצוין! אולי אפילו תריצו כלי Lint שייתן לכם ציון 100. מצוין!

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


A Developer in the process of integrating a 3rd Party API -- Caravaggio, 1594


איך מתכננים API טוב?


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

חלילה, אני לא אומר שלהגדיר API פשוט ומובן עם naming טוב זה דבר קל.
אבל האם יש יותר מזה?



API טוב מתוכנן מנקודת המבט של הלקוח - לא של היצרן

טעות ראשונה שאני רואה שחוזרת על עצמה היא API שעולם המונחים שלו משרת את היצרן (System A) - ולא את הלקוח.

בואו נראה צמד פעולות לדוגמה:

SimulatePurchaseWithoutSaving(...) --> simulationId
ApplyAndSave(simulationId, ...) 

SimulatePurchaseWithoutSaving הוא דוגמה טובה לשם של פעולה ״בראש״ של היצרן.
את הלקוח לא מעניין מה אני שומר ומה לא.
האם מעניין אותו לבצע סימולציה?

מנקודת המבט של הלקוח כנראה שעדיף

PurchaseABC(...) --> purchaseId
ConfirmPurchase(purchaseId, ...)

חשוב מאוד שה API ישקף את האינטרס של הלקוח. מדוע הוא קורא ל API הזה בכלל? מה הוא רוצה להשיג?
חשוב להשתמש במונחים שרלוונטיים אליו, ולהימנע מכל מה שלא (למשל: האם אנחנו שומרים משהו או לא = אינו רלוונטי ללקוח).
מה יותר הגיוני? API בשם receiveEmailAndPassword או API בשם login?

כלל חשוב לזכור:
FOCUSING ON HOW THINGS WORK LEADS TO COMPLICATED INTERFACES

עדיין לא ראיתי מישהו שקרא ל Login ״שלח שם משתמש וסיסמה״ - אבל ראיתי דוגמאות רבות שקולות לה. קצת הגזמתי - בכדי להדגיש את העיקרון.
בעיה נוספת: "receive" הוא שם פעולה סבילה מצד היצרן של ה API. זה לא מונח או נקודת ייחוס שצריכה להיות חלק מ API.

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



Leaking Abstractions


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

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

כאן גם הבעיה. העולם משתנה, הביזנס משתנה --> ולכן גם המערכת שלנו צריכה להשתנות.
שינויים רבים הם extensions - להוסיף עוד למערכת, שינויים שלא ״שוברים״ APIs.

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

אבל מה עם API פנימי? האם גם שם צריך להיזהר? בוודאי שכן!

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

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

לכאורה נשמע שהגישה המחמירה היא הטובה, בעוד הגישה המקלה (שעדיין פורחת בתעשייה, במיוחד ברצון ל ״Devliery מהיר״) - היא מתכון לאטיות פיתוח בעתיד.

בסופו של דבר זהו tradeoff. בהחלט הגישה המתירנית יכולה להסתיים באסון. בהחלט הגישה המחמירה גוררת עוד עבודה --> מפחיתה את מהירות פיתוח המערכת.

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

קשה לי להדגיש במידה מספיקה כמה ״חסכון של שעה״ היום, יכול להפוך לשבוע עבודה בעוד כמה חודשים. כמה פעמים "API קטן עם צרכן בודד״ הופך בלי משים לב ל ״API מרכזי ב flow קריטי במערכת״ - שאסור לגעת בו.

טכנולוגיות מגניבות כמו GraphQL לעתים מקלות על זליגת ההפשטות. המותג החזק ("GraphQL", ווהאו! פייסבוק! גוגל! זום!) מפחית את ההגנות שלנו בפני מה שעשוי להתהוות של ״סטטוס קוו״ שלא נצליח לעולם לשנות אותו.

מערכת שלא מתפתחת, ולא משתנה - היא מערכת Legacy. היא ״עושה את העבודה״, אבל לאט לאט היא לא מצליחה לעמוד בתחרות מול גישות ומגמות חדשות.


הבה נתייחס לתסריט הייחוס הבא:


המערכת (או מיקרו-שירות) שלנו היא מערכת A, ואנו חושפים את API a ללקוח כלשהו.
על מנת לספק את הבקשה, עלינו לפנות ל API b של מערכת B.

  • אל תחשפו ב API a רכיבים / אובייקטים מ API b. אתם קושרים את הלקוחות של Service A גם ל Service B - מה שיקשה מאוד על Service B להשתנות לאורך הזמן.
    • שכפלו אובייקטים. אובייקט Customer של API a יכול להיות זהה לחלוטין לאובייקט Customer של API b - וגם לדרוש העתקה. זו תקורה - אבל היא משתלמת לאורך זמן. כאשר API b ירצה להשתנות - הוא יכול, ורק יהיה צריך לשנות את לוגיקת ההעתקה בין האובייקטים.
  • אל תחשפו אובייקטים שלמים / עשירים מדי. יש משהו מאוד נוח, אך הרסני, בחשיפת API של קריאה / עדכון של אובייקטים שלמים של המערכת. האחריות של המערכת על האובייקטים שלה - פשוט אובדת.
    כאשר המערכת שלכם תצטרך לשנות את האובייקטים הללו בכדי לתאר התפתחות במערכת - זה יהיה קשה מאוד, ואולי בלתי אפשרי: שימושים שונים ותלויות מול האובייקטים הללו התפתחו בשאר המערכת - סוג של ״עבודה לא מתוכננת״, ואולי מאוד משמעותית - שנוספה לשינוי פשוט של API.
    • מדוע גוף האדם לא חושף את האיברים הפנימיים לעולם החיצון, שלא דרך מנגנונים מבוקרים? אולי אפשר ללמוד משהו מהטבע על תכנון מערכות מוצלחות.
    • צרו אובייקט נתונים עבור ה API (מה שנקרא גם DTO) ובצעו העתקה פשוטה בין האובייקט הפנימי (שיוכל להשתנות) לזה שאתם כובלים את עצמכם אליו לזמן בלתי-נשלט. זו השקעה טובה לטווח ארוך.
      • העתקה גם חשובה לצורך Immutability. במיוחד ב API של קוד באותה המכונה - אתם לא רוצים שמישהו יקבל אובייקט פנימי ואז ישנה לכם אותו.
    • חשפו באובייקט של ה API רק מה שהלקוח צריך. אל תהיו ״נדיבים מדיי״. צריך בכלל הזה גם לא להגזים:
      • אפשר לשלוח אובייקט עם 6 שדות - גם אם הלקוח זקוק רק ל 2, כל עוד אלו 4 שדות שהיה הגיוני לשלוח, לו הלקוח היה מבקש.
      • אפשר לשתף אובייקטים בין APIs שונים בתוך Service A. פיצול אובייקטים בתוך אותו שירות - הוא לא שינוי קשה מדי.
      • הגזמה ברמת הדיוק של ״לשלוח בדיוק מה שהלקוח צריך״ - תגרום לעיכובים בהתפתחות המערכת, דווקא מתוך התגוננות יתר. גם זה לא מצב טוב.
  • זכרו ש API הוא חוזה מחייב -- אבל זה לא חוזה שמכסה את כל הפרטים. ה compiler יצעק עלינו אם נשנה טיפוס או נסיר שדה מה API. הוא לא יצעק אם נזרוק Exception במקום שלא זרקנו בעבר או נחזיר מרחב ערכים שונה (גדול?) מזה שהחזרנו בעבר. כלומר: יש שדה מסוג String - אבל התחלנו להחזיר ערכים חדשים שהלקוחות לא יודעים להתמודד איתם.
    • כדי לוודא שה API לא משתנה ופוגע בלקוחות שלכם - צרו Automated Tests לבדוק את האלמנטים ב״חוזה״ שהקומפיילר לא יודע לתפוס.
    • התאימו את כמות הבדיקות והיסודיות שלהם - לכמות הלקוחות / חשיבות ה API. בדיקה שלעולם לא תכשל - היא בזבוז זמן לכתיבה. אנו עוסקים בניהול סיכונים.



כמה דילמות נפוצות


API אחד המחזיר היררכיה גדולה של אובייקטים - מול API לכל אובייקט קטן בהיררכיה?

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

כמובן שיש פה Tradeoff: אם מדובר ב API לצורך monitoring או בדיקות - אז חלוקה ל API קטנים יהיה בזבוז זמן. חשוב להבין כמה שינוי אפשרי אתם מסכנים, תמורת כמה חסכון בזמן בפיצול ה API.

אם מדובר ב API בין Front-End ל Back-End ואתם מאחדים לאובייקטים גדולים כדי לחסוך latency של קריאות ברשת - אז עשו את החיבור ברמה של API Gateway - ובטח לא ברמת ה API של ה Back-End.



״למתוח״ API כדי להתאימו לצרכים, מול יצירה של גרסה חדשה?

זה תלוי במקרה - אין לי תשובה גנרית. רק אבקש שאל תפחדו ליצור גרסה 3,2 ו 4 של API. המערכת מתפתחת ו API צריכים להתחדש גם כן. גרסאות עוזרות לעשות מעבר מדורג, שלעתים הוא המעבר היחידי האפשרי.


מתי לזרוק Exception מ API? מתי להחזיר ״אובייקט כישלון״?

אפשר לעסוק בשאלה הזו בלי סוף. מה שחשוב הוא:
  • כשיש תקלה - יהיה ברור ללקוח ה API שזה מה שקרה. עדיף להוסיף הודעת שגיאה שימושית שממנה ניתן ללמוד מה אפשר לעשות אחרת בכדי להצליח (אם אפשר).
  • להיות עקביים. אל תחזירו לפעמים שגיאה ולעתים ״אובייקט כישלון״


יש לי שני לקוחות ל API - כל אחד צריך מידע מעט אחר. האם להוסיף את הלקוח כפרמטר ל API או להגדיר שני APIs שונים?

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

אני לא אוהב את הפתרון של ״פרמטר עם מזהה הלקוח״ כי הוא קושר בין שני שימושים שונים זה-לזה. אני מעדיף 2 endpoints שונים, ואם הם עושים שימוש חוזר בקוד פנימי - אדרבא.

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


למה ב Next-Insurance בחרנו לא להשתמש ב REST?

ב Next-Insurance ניסינו (כמו רבים אחרים) להיצמד לכללי ה REST בכדי ליצור אחידות ב APIs הפנימיים, ולהפוך אותם לצפויים יותר לשימוש. ל REST יש כמה בעיות ידועות כמו המגבלה להעביר payload גדול על קריאת get, או ההגדרות הלא מדויקות והניתנות לפרשנות של REST כרעיון (מעולם לא היה תקן מסודר, ומעולם לא היו פיתוחים מוסכמים ל REST מעבר למסמך הראשוני). למשל: קשה מאוד להתיישר על סכמת URLs עקבית בקבוצה גדולה של אנשים. לאנשים רבים יש פרשנויות רבות כיצד URL שהוא RESTful צריך להיראות.

לכאורה, בשלב מסיום - הבנו שאנחנו לא מצליחים לאמץ REST בצורה גורפת. הוריאציות השונות של ה APIs שנוצרו, והחריגות מעקרונות ה REST (מתוך אי-ידיעה, או אי-הקפדה) - יצרו בלאגן. לא השגנו עקביות ב APIs ברמת המערכת.

לא התעקשנו, כי הבנו שזו לא הבעיה העיקרית של המערכת שלנו. היו לנו דברים חשובים יותר להתמקד בהם.

מפה לשם, עברנו ל JSON over HTTP בתצורה מסוימת. תמיד משתמשים ב HTTP POST ותמיד ה API מגדיר אובייקט (DTO) בקשה ואובייקט תשובה שעליו ישבו הפרמטרים. ה URL הוא רצף מילים שקשור לפעולה, לפעמים RESTFul - אבל לא בהכרח.

הגישה הזו הצליחה דווקא דיי יפה. הפסיקו על הויכוחים על דקויות/פרשנויות של REST (במחיר זמן שימושי שעתה זמין לשיפורים אחרים במערכת). קיומם של אובייקטי Request ו Response הפכו הוספה של פרמטרים לקלים יותר, מבלי ״לשבור״ את ה API. המערכת - נראית עקבית הרבה יותר, והיא פשוטה.

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


עוד כמה קלישאות (נכונות):
  • API צריך להיות קל לשימוש, וקשה לשימוש לא-נכון.
  • בכדי לעצב API לא צריך ניירת או תהליכי חשיבה ארוכים. צרו טיוטא מהירה של ה API וכתבו קוד שמשתמש ב API הזה. זו הדרך הטובה לחשוב וללטש את ה API.
  • צייתו ל Principle Of Least Astonishment (בקיצור: POLA). 
    • ה API לא צריך להפתיע את המשתמש. ככל שהמשתמש של ה API רחוק מכם יותר - הכלל הופך לחשוב אפילו יותר.
  • השתמשו ב APIs בתבניות (Format) הנוח ללקוח, ולא למערכת. יש מין טעות כזו ש API צריך להיות נוח ליצרן ולא ללקוח.
    • אולי אתם מייצגים זמן ב Java Epoch, אבל ללקוח יהיה הרבה יותר קל לעבוד בתאריכים קריאים, קרי 2020-04-19.
  • API הוא רכיב קריטי באבטחת המערכת. זה זמן טוב להזכיר שיש OWASP Top 10 ל APIs.


סיכום


תכנון API היא עוד מלאכה בסיסית ותדירה בהנדסת תוכנה, מלאכה שיש בה מיומנות שתמיד אפשר לשפר. בפוסט ניסיתי להתמקד בבעיות ״מהשטח״ - שנתקלתי בהן שוב ושוב לאורך השנים.

שיהיה בהצלחה!


----

[א] סגנונות API נפוצים הם Falcor, gRPC, SOAP, RPC, GraphQL, REST או סתם JSON over HTTP.

----

קישורים רלוונטיים

Public APIs, like diamonds, are forever


2020-03-14

עבודה מרחוק (וירוסים, קדמה, או סיבות אחרות)

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

השאלה הראשונה שעולה היא ״איך מתמקדים בעבודה ולא ׳זולגים׳ פעם אחר פעם לפייסבוק או קאנדי קראש (או מה שפופולארי עכשיו)?״

השאלה השנייה היא - ״איך לעזאזל אני יכול להתרכז בעבודה עם ילדים בבית?״


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

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

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

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


מה שונה בעצם בעבודה מבוזרת?


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

האם באמת ״היכולת לעבוד מרחוק״ היא תכונת-אופי, או סביבת-עבודה ותרבות שכל אדם יכול לאמץ? אין לי תשובה ברורה - אבל אני מאמין שהתשובה היא איפשהו באמצע.

במקרה של רובנו - העבודה מרחוק כרגע ״נפלה״ עלינו בלי להתחשב ברצונותנו. הארגון שלנו לא גייס אותנו בגלל ש״אנחנו מתאימים לעבודה מרחוק״.

מה זה אומר, ״לעבוד יעיל״ מרחוק?


כלים

מחשבה ראשונה נפוצה, היא שעבודה מרחוק היא עניין של תפעול כלי-תקשורת (סלאק, זום, מייל, גוגל דרייב, trello, וכו׳).

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

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


טריגרים

המוח שלנו עושה הרבה עבודה שאנו לא מודעים אליה. כאשר אנחנו עוברים context-switch במהלך יום העבודה, ישנם רגעים בהם אנחנו מסתכלים סביב ושואלים את עצמנו: ״שניה! איפה אני? מה קורה עכשיו?״. השאלה והתשבה הן דיי מיידיות - ואנחנו לא שמים לב אליהן.

אם התשובה לשאלה הראשונה היא ״במשרד״, ההקשר המיידי הוא ״אנחנו בעבודה. בואו נחשוב מה עלינו לעשות שקשור לעבודה״.

אם התשובה לשאלה הראשונה היא ״על הספה בסלון. בפיג׳מה״ - יש מגוון תשובות שונות שעשויות לקפוץ לנו לשאלה השנייה מלבד ״אנחנו בעבודה. בואו נחשוב מה עלינו לעשות שקשור לעבודה״. זה טבעי.





הפער הגדול ביותר, כנראה, בין עבודה במשרד לעבודה בבית, היא שבמשרד יש לנו הרבה טריגרים (triggers) המחברים אותנו לעשייה של מקום העבודה שלא קיימים בבית. בבית אפילו יש לנו טריגרים מבלבלים אחרים (ספה, טלויזיה, מקרר, רשימת סידורים על המקרר, X-Box, משפחה, לא חסר...) - המקשרים אותנו לדברים אחרים.

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

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

ישנם מקצועות שבהם יש הרבה טריגרים חיצוניים שיקשרו אתכם לעבודה. דוגמה קיצונית: שירות לקוחות בה הטלפונים לא מפסיקים לצלצל. במקצוע הנדסת התוכנה - יש פחות טריגרים כאלו מובנים.
אם הצוות שלכם עובד ביחד ובאצוות קטנות (small batches) - יהיו לכם באופן טבעי יותר טריגרים. עבודה ב״ספרינטים״ ארוכים (נאמר: חודש) - היא הרבה יותר מאתגרת.

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


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



גבולות

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

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

איזון

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

כשהעבודה מהבית מצליחה להיות יעילה - שבחו את עצמכם. זה הישג, וזה לא מובן מאליו!


תקשורת 

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

האם תמונה של חברי-הצוות על שולחן-העבודה יכולה לעזור? זו עצה כבר יותר ״רכה״. נסו ותראו.


הרבו בתקשורת בפורום קטן (למשל, צוות), מעטו תקשורת בפורום הכללי.

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

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

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

שפרו תקשורת טכנית

Technical communication skill - היא מיומנות חשובה, בלי קשר לעבודה מרחוק:
  • לתמצת רעיון טכני ולהסביר אותו בפשטות. למשל: השמטת פרטים טפלים, שימוש במטאפורות מוצלחות וכו׳.
  • להבין מי הקהל, מה מידת ההבנה שלו בנושא, ומה מעניין אותו - בכדי להתאים את ההסבר לקהל.
  • להקשיב לשאלות / דאגות של המאזינים - ולהצליח להתייחס אליהן בצורה יעילה.
במשרד המשותף, לרוע המזל, המיומנות הזו לא מתפתחת באופן מיטבי: תמיד יכול להיות מישהו בסביבה ששומע בחצי אוזן את השיחה, או קל מאוד לצרף אותו לדיון - והוא יתערב ויעזור.

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

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

בתקשורת יותר verbose (למשל מייל או מסמך), נסו להקדיש עוד כמה דקות לפני השליחה, ולדמיין אחד מהנמענים קורא את מה שכתבתם. שפרו עד שהמסר יהיה חד וברור.

עד כמה הצלחתם? כמה שאלות עלו? - יש לכם מירב הזדמנויות לשפר את המיומנות החשובה הזו.


ניהול אנשים מרחוק


יש גבול עדין בין לעקוב אחרי ביצועים ויצירת אווירה של אי-אמון.

החשש הגדול ביותר של מנהלים בעבודה מרחוק הוא כנראה: ״כיצד אני יודע שהם בכלל עובדים?״


שעות עבודה

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

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

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

יותר מזה: נסו לכבות את ה "online indicators״ בכלים בהם אתם עובדים, אולי תגלו שעדיף בלעדיהם.


השקעה מול תפוקה

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

אם אתם עובדים בארגון של CI, אז יש לכם כלל חשוב שאומר: ״כל מפתח מבצע לפחות commit ל master כל יום״. בעבודה מרחוק אני חושב שרלוונטי אפילו יותר לוודא שהכלל הזה עובד. מעורבות שלכם בקוד ומתן הערות - יעזרו לשמר אווירת עבודה. אם מישהו לא ביצע commit כבר יומיים - זה אולי מקום להעיר לו, ולשפר את הפרקטיקה:
  • סגנון פחות מוצלח: ״לא עשית commit היום! איך אני יודע שאתה עובד?״
  • סגנון יותר מוצלח: ״עבודה ב batches קטנים היא יעילה יותר בכלל, אבל היא גם עוזרת להישאר מחובר לארגון שלנו ולקצב העבודה. בוא נעשה מאמץ לשמר את הכלי הזה״.


מוטיבציה

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

עבודה מרוחקת מגבירה את הצורך של העובדים בחיבור ומוטיבצה למה שהם עושים: ״מה המשמעות של מה שאני עושה?״, ״מי מחכה לזה?״, ״כמה חשוב לעשות את זה טוב?״, וכד׳.

יותר יעיל להתמקד בשאלות הללו ולגרום לכך שיהיו להן תשובות מוצלחות, מאשר לחשוב ״האם העובד שלי באמת יושב ועובד?״.

Batches קצרים (ימים!, לא שבועות), הגדרת הפיצ׳רים בצורה מדידה, חיבור המפתח ללקוחות שלו (לקוחות קצה, או המפתח הבא שישתמש בפיצ׳ר), וכו׳ - הם כלים חשובים אפילו יותר בעבודה מרוחקת.


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

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


פערי זמן

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

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

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

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

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

האם עובד שמתחבר 5 שעות אחרי כל השאר יכול בקלות יחסית להשלים את שרשרת האירועים והדיונים שהיו? בכדי להצליח - חשוב שזה יהיה אפשרי, קרי: יש לייצר תיעוד ושיתוף של מה שמתרחש. הייתה לכם שיחת טלפון חשובה בין 3 מפתחים? כתבו 2 שורות בסלאק של הצוות עם הסיכום שלה.


סיכום


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

שיהיה בהצלחה!




קישורים רלוונטיים:

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

״תקועים בבית?״ - סט פעילויות איכותי לילדים של מכון דוידסון