none
תכנון של API מול DB שעובד רק עם JSON RRS feed

  • שאלה

  • שלום לכולם!

    אני מתכננת API שעובד מול DB מסויים. (MYSQL /MSSQL)

    כל הפעולות מול ה DB נעשות רק בעזרת פרוצדורות. אין שום קריאה ישירה לטבלה או לVW

    יותר מכך, לכל פרוצדורה יש פרמטר אחד מסוג JSON שהוא INOUT.

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

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

    עד כה הטקטיקה הזו הוכיחה את עצמה. 

    השאלה שלי היא זו: אני מתכננת לכתוב API שעובד מול ה DB המתואר

    אני מבינה שבצורה המתוארת (בהתעלם כרגע מה JWT) המבנה שלו הוא למעשה ללא EF עם קונטרולר? מודול?

    אשמח לעצות או הכוונה בדרך הנכונה של המבנה לכתוב את ה API מול ה DB הזה

    תודה!

    שני


    שבת 06 יוני 2020 07:27

תשובות

  • שלום שני,

    האם תוכלי בבקשה לספר יותר פרטים? האם את עובדת ב- Asp.net Core, ב- Asp.Net (.Net Framework), או האם בכלל בספריה אחרת?

    מה הסיבה לכך שכל הפעולות מול ה- DB נעשות ב- Stored Procedure אם רובן פעולות CRUD פשוטות?

    את יכולה לבנות שאילתות דינאמיות בשרת ולתשאל את ה- Db (עם או בלי Stored Procedure) בלי הצורך לשנות את החתימה ו/או את יכולה להשתמש ב- EF ו- Linq (גם בלי EF) כדי לבנות שאילתות דינאמיות (בלי שימוש ב- T-SQL).

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

    בכל מקרה, גם אם את הולכת לכיוון שאת מציעה, המערכת צריכה להיות מחולקת בצורה מודולרית (ללא קשר לטכנולוגיה כגון EF),וה - Json או הפרמטר שאת שולחת ל- DB אמור להיות מוכר רק לשכבה שמתקשרת עם ה- DB ולא לשכבות אחרות. ז"א המידול של ה- Rest API שלך לא אמור לדעת על הצורה בה נעשית התקשורת עם ה- DB.

    אם תוכלי לענות על השאלות ולספק יותר מידע כך נוכל לעזור לך יותר :)

    בהצלחה!

    מואייד

    שבת 06 יוני 2020 19:59
  • שלום שני וכמובן שלום Moaid

    ברוכים הבאים לפורומים של MSDN 😀 כל כך כיף לראות אתכם מצטרפים אלינו לקהילה (טוב אני יותר פעיל בפורום של SQL אבל זו אותה מערכת אחרי הכל)

    Moaid, כיצד כותבים את השם שלך בעברית?!? אני לא בטוח אפילו איך לבטא אותו וזה אחרי שעוד דיברנו מעל לשעה 🤣

    שני, את יכולה לענות בבקשה על השאלות של Moaid כדי לעזור לכוון את מי שעוזר למסלול המתאים לך?

    בינתיים אני יכול להוסיף כמה נקודות קטנות כלליות:

    1. הסיבה העיקרית (אם כי לא היחידה) היא גמישות של הפרוצדורה.

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

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

    אז מה הסיבה האמיתי שיש ייתרון בפרוצדורות?

    הנה הסבר מקוצר אבל מעמיק ומדוייק על מה קורה מאחורי הקלעים בשרת 😀...

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

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

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

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

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

    מה שמתואר למעלה נעשה עבור כל שאילתה וכל פרוצדורה בפעם הראשונה שהשרת מקבל שאילתה חדשה להריץ!

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

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

    אז מה הייתרון בפרוצדורה על פני קוד של שאילהת ישירה?

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

    לעומת זאת אם רושמים שאילתה כמו

    select c from tbl where id=2

    אז בכל פעם שמשנים ולא פסיק מהשאילתה אז השרת צריך לקמפל את השאילתה מחדש ולבחור תוכנית הרצה מחדש (תהליך ארוך וכבד!). אם נריץ את אותה שאילתה ובמקום 2 נעשה שימוש ב 3 אז מבחינת השרת זה שאילתה אחרת וצריך לבצע הכל מההתחלה

    אבל בפרוצדורה אם זה פרמטר אז השרת יכול לעשות שימוש בתוכנית הקודמת מכיוון שהוא מבין שזה "רק פרמטר"

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

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

    2. אני מבינה שבצורה המתוארת (בהתעלם כרגע מה JWT) המבנה שלו הוא למעשה ללא EF עם קונטרולר? מודול?

    לא מדוייק.

    JSON Web Token הוא סטנדרד פתוח להעברת מידע בין 2 ישויות (למשל שרת ולקוח). 

    entity framework זה בסך הכל סביבת object-relational mapping (בקיצור ORM) או במילים אחרות זה אוסף של מחלקות אשר עוזרות לנהל את המידע על ידי מיפוי למבנה אובייקטים (אשר יותר מחובר לצד של המפתחים מאשר האופן בו נשמר המידע במדי הנתונים למשל). דרך אגב, ORM הוא כלי שנועד רק לפתחים ולעולם לא נועד לשיפור ביצועים אלא רק לנוחות ושיפור תהליך הפיתוח.

    לשימחתך EF עובד בצורה מלאה עם JWT ולכן זה מקל את החיים.

    אין שום בעיה לעבוד עם EF במודל שאת מדברת.

    בקישור הבא יש דומה מלאה של צעד אחרי צעד לפרוייקט שיכול ללמד את כל התהליך:

    How to Build CRUD REST APIs with ASP.NET Core 3.1 and Entity Framework Core, Create JWT Tokens, and Secure APIs

    זה לא אומר שצריך לבעוד עם EF וזה לא אומר שזה הבחירה הנכונה. למשעה אני חוזר על מה שכתבתי מעל: ORM הוא כלי שנועד רק לפתחים ולעולם לא נועד לשיפור ביצועים אלא רק לנוחות ושיפור תהליך הפיתוח. למשל מערכות real time ממש אבל ממש לא מומלץ לנסות לפתוח בעזרת ORM בדרך כלל.

    3. אשמח לעצות או הכוונה בדרך הנכונה של המבנה לכתוב את ה API מול ה DB הזה

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

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

    בינתיים תבדקי אם הקישור שממתי על עוזר לך :-)


    signature   Ronen Ariely
     [Personal Site]    [Blog]    [Facebook]    [Linkedin]





    יום ראשון 07 יוני 2020 15:22
    מנחה דיון

כל התגובות

  • שלום שני,

    האם תוכלי בבקשה לספר יותר פרטים? האם את עובדת ב- Asp.net Core, ב- Asp.Net (.Net Framework), או האם בכלל בספריה אחרת?

    מה הסיבה לכך שכל הפעולות מול ה- DB נעשות ב- Stored Procedure אם רובן פעולות CRUD פשוטות?

    את יכולה לבנות שאילתות דינאמיות בשרת ולתשאל את ה- Db (עם או בלי Stored Procedure) בלי הצורך לשנות את החתימה ו/או את יכולה להשתמש ב- EF ו- Linq (גם בלי EF) כדי לבנות שאילתות דינאמיות (בלי שימוש ב- T-SQL).

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

    בכל מקרה, גם אם את הולכת לכיוון שאת מציעה, המערכת צריכה להיות מחולקת בצורה מודולרית (ללא קשר לטכנולוגיה כגון EF),וה - Json או הפרמטר שאת שולחת ל- DB אמור להיות מוכר רק לשכבה שמתקשרת עם ה- DB ולא לשכבות אחרות. ז"א המידול של ה- Rest API שלך לא אמור לדעת על הצורה בה נעשית התקשורת עם ה- DB.

    אם תוכלי לענות על השאלות ולספק יותר מידע כך נוכל לעזור לך יותר :)

    בהצלחה!

    מואייד

    שבת 06 יוני 2020 19:59
  • שלום שני וכמובן שלום Moaid

    ברוכים הבאים לפורומים של MSDN 😀 כל כך כיף לראות אתכם מצטרפים אלינו לקהילה (טוב אני יותר פעיל בפורום של SQL אבל זו אותה מערכת אחרי הכל)

    Moaid, כיצד כותבים את השם שלך בעברית?!? אני לא בטוח אפילו איך לבטא אותו וזה אחרי שעוד דיברנו מעל לשעה 🤣

    שני, את יכולה לענות בבקשה על השאלות של Moaid כדי לעזור לכוון את מי שעוזר למסלול המתאים לך?

    בינתיים אני יכול להוסיף כמה נקודות קטנות כלליות:

    1. הסיבה העיקרית (אם כי לא היחידה) היא גמישות של הפרוצדורה.

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

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

    אז מה הסיבה האמיתי שיש ייתרון בפרוצדורות?

    הנה הסבר מקוצר אבל מעמיק ומדוייק על מה קורה מאחורי הקלעים בשרת 😀...

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

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

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

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

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

    מה שמתואר למעלה נעשה עבור כל שאילתה וכל פרוצדורה בפעם הראשונה שהשרת מקבל שאילתה חדשה להריץ!

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

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

    אז מה הייתרון בפרוצדורה על פני קוד של שאילהת ישירה?

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

    לעומת זאת אם רושמים שאילתה כמו

    select c from tbl where id=2

    אז בכל פעם שמשנים ולא פסיק מהשאילתה אז השרת צריך לקמפל את השאילתה מחדש ולבחור תוכנית הרצה מחדש (תהליך ארוך וכבד!). אם נריץ את אותה שאילתה ובמקום 2 נעשה שימוש ב 3 אז מבחינת השרת זה שאילתה אחרת וצריך לבצע הכל מההתחלה

    אבל בפרוצדורה אם זה פרמטר אז השרת יכול לעשות שימוש בתוכנית הקודמת מכיוון שהוא מבין שזה "רק פרמטר"

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

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

    2. אני מבינה שבצורה המתוארת (בהתעלם כרגע מה JWT) המבנה שלו הוא למעשה ללא EF עם קונטרולר? מודול?

    לא מדוייק.

    JSON Web Token הוא סטנדרד פתוח להעברת מידע בין 2 ישויות (למשל שרת ולקוח). 

    entity framework זה בסך הכל סביבת object-relational mapping (בקיצור ORM) או במילים אחרות זה אוסף של מחלקות אשר עוזרות לנהל את המידע על ידי מיפוי למבנה אובייקטים (אשר יותר מחובר לצד של המפתחים מאשר האופן בו נשמר המידע במדי הנתונים למשל). דרך אגב, ORM הוא כלי שנועד רק לפתחים ולעולם לא נועד לשיפור ביצועים אלא רק לנוחות ושיפור תהליך הפיתוח.

    לשימחתך EF עובד בצורה מלאה עם JWT ולכן זה מקל את החיים.

    אין שום בעיה לעבוד עם EF במודל שאת מדברת.

    בקישור הבא יש דומה מלאה של צעד אחרי צעד לפרוייקט שיכול ללמד את כל התהליך:

    How to Build CRUD REST APIs with ASP.NET Core 3.1 and Entity Framework Core, Create JWT Tokens, and Secure APIs

    זה לא אומר שצריך לבעוד עם EF וזה לא אומר שזה הבחירה הנכונה. למשעה אני חוזר על מה שכתבתי מעל: ORM הוא כלי שנועד רק לפתחים ולעולם לא נועד לשיפור ביצועים אלא רק לנוחות ושיפור תהליך הפיתוח. למשל מערכות real time ממש אבל ממש לא מומלץ לנסות לפתוח בעזרת ORM בדרך כלל.

    3. אשמח לעצות או הכוונה בדרך הנכונה של המבנה לכתוב את ה API מול ה DB הזה

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

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

    בינתיים תבדקי אם הקישור שממתי על עוזר לך :-)


    signature   Ronen Ariely
     [Personal Site]    [Blog]    [Facebook]    [Linkedin]





    יום ראשון 07 יוני 2020 15:22
    מנחה דיון
  • משהו קטן Off-topic לגבי תוכניות הרצה

    אם אתם רוצים (מאוד מומלץ!) לבדוק את תוכנית ההרצה שהשרת בחר עבור שאילתה חדשה שאתם כותבים או פרוצדורה למשל, אז אתם יכולים לעשות את זה בלחיצת כפתור בתוכנת ה SQL Server Management Studio או בתוכנת ה Azure Data Studio.

    הנה המדריך הרשמי של מייקרוסופט עם תמונות והסבר נהדר בעבודה עם ה SSMS

    https://docs.microsoft.com/en-us/sql/relational-databases/performance/display-an-actual-execution-plan?view=sql-server-ver15


    signature   Ronen Ariely
     [Personal Site]    [Blog]    [Facebook]    [Linkedin]

    יום ראשון 07 יוני 2020 15:28
    מנחה דיון
  • שלום שני

    עוד קצת OFF-TOPIC

    EF הוא פריוומרק יחסית כבר ואם את לא באמת צריכה את כל הפונקציונליות שלו אפשר לשקול חלופות כמו dapper שאומנם אין לו את כל היכולות של EF אבל הוא הרבה יותר קל ממנו



    יום שני 08 יוני 2020 10:12
  • אני לא מכיר את dapper אבל בהחלט זה נכון שעבודה עם ORM יכולה להיות כבשה ובדרך כלל צורכת יותר משאבים מעבודה ישירה עם שאילתות שאנחנו כותבים

    signature   Ronen Ariely
     [Personal Site]    [Blog]    [Facebook]    [Linkedin]

    יום שני 08 יוני 2020 13:57
    מנחה דיון