
joi, שאחראית על ולידציה ולא על אקספרס עצמה.validate מחזירה תוצאה. אם יש בה error, שולחים סטטוס 400 עם רשימת ההודעות, ועושים return כדי שלא ייכתב כלום למסד הנתונים.abortEarly: false כדי לקבל את כל השגיאות יחד.postValidationSchema.הטקסט המלא של הדקות הראשונות בהרצאה «ביצוע ולידציה על POST Requests» בקורס הווידאו של PracticU – כתוביות בעברית עם זמן התחלה לכל פסקה. כך תוכלו לקרוא ולחפש את הנושאים לפני שמתחילים ללמוד.
אז אנחנו רוצים לעבור לביצוע ולידציה בצד השרת. מה זה בעצם אומר? אנחנו רוצים לבדוק שהמידע שהיוזר שולח לנו עבור כל מיני בקשות, לדוגמה עבור הוספה של מוצר או עדכון של מוצר וכדומה, הוא מידע חוקי מבחינתנו, אנחנו מגדירים מה החוקיות.
אם לדוגמה מבחינתי כשהיוזר מוסיף מוצר הוא חייב להביא לי את השם של המוצר, הוא לא יכול לא להביא לי את השם של המוצר, שם של מוצר זה דבר שהוא שדה חובה מבחינתי, אז כשהוא שולח לי מוצר והוא לא מביא לי את השם, זה לא הגיוני שאני אתן לו שגיאת 404. כן, 404 זה משהו לא נמצא, מה הקשר ל-404?
ולא הגיוני שאני אתן לו שגיאת 500, כי 500 זה אומר שהייתה לי קריסה, אבל לא הייתה לי קריסה, הוא פשוט שלח לי מוצר פגום או מוצר בלי שם.
אז השגיאה שאנחנו צריכים להחזיר לו זה שגיאה עם מספר 400. זה bad request וזה כל דבר שקשור לוולידציה שנכשלה עקב מידע שגוי שהיוזר הביא. בואו נעבור רגע לקונטרולר ונעבור שלב שלב ונראה איזה routes כאן היוזר שולח לי מידע.
כאשר היוזר רוצה לקבל את כל המוצרים הוא לא שולח לי שום מידע אין לי פה משהו שקשור לוולידציה שאני צריך לעשות. כאשר היוזר רוצה לקבל מוצר ספציפי הוא שולח לי את ה-ID כאן הוא יכול לשלוח ID שלא נמצא אבל אם הוא שולח לי ID שלא נמצא, לדוגמה הוא שולח לי 700 ואין לי מוצר 700 אז אנחנו כבר טיפלנו בזה בצורה נכונה.
כאשר ID לא נמצא אני נותן לו 404 במקרה והוא רוצה לקבל מוצר כזה לא במקרה שהוא רוצה למחוק ID שלא נמצא אבל אולי הוא שולח לי ID ABC ו-ABC זה בכלל לא מספר אז אולי במקרה הזה אני כן רוצה לבצע לו ולידציה אז את זה נזכור, יכול להיות שבמקרה הזה כן נבצע לו איזושהי ולידציה מסוימת, נטפל בזה.
כאשר הוא רוצה להוסיף מוצר חדש, אז אני רואה שיש לנו פה כל מיני דברים שהוא נותן לי, שם, מחיר, כמות במלאי, כל הדברים האלה כמובן יכולים להיות שגויים.
הוא יכול להביא לי מחיר שם שהוא לא לפי חוקיות שלי, נניח שם קצר מדי או ארוך מדי. הוא יכול להביא לי בעסיקלי מחיר שלילי, כל מיני דברים כאלה שאני כן רוצה לבצע ולידציה.
כאשר הוא מבצע עדכון מלא אותו סיפור, כאשר הוא מבצע עדכון חלקי אותו סיפור, הוא נותן לי שם, אולי השם בעצם הוא לא חוקי, וכאשר הוא מבצע מחיקה אני גם רואה ID, כאן אם ה-ID לא קיים אז אני לא אומר לו שזה לא בסדר, אבל אולי אם ה-ID ABC והוא לא מספר אני כן רוצה להגיד לו שזה לא בסדר.
אז אנחנו רואים שיש לנו פה הרבה דברים שאנחנו צריכים לטפל בהם, ויש לנו עוד דבר אחד שאנחנו צריכים להבין, שהטיפול, בואו נניח בהוספה יכול להיות טיפה שונה מעדכון.
למה? כי יכול להיות שבהוספה, הוספה, סליחה, זה פה, הוא לא צריך לתת לי בכלל איי-די, וכאשר הוא מעדכן הוא חייב לספק לי איזשהו איי-די.
או יכול להיות מצב שבעדכון מלא הוא חייב לתת לי שם ומחיר וכמות במלאי, בעדכון חלקי בפאץ' אז הוא לא חייב לתת לי כל אחד מהם ומשהו שגם כן אנחנו צריכים לטפל בו בצורה שונה. אז אנחנו רואים שיכול להיות מצב שהמידע שהוא שולח בין הוספה, בין עדכון מלא לבין עדכון חלקי הוא יכול להיות טיפה שונה מבחינת הוולידציה, זאת אומרת שאנחנו צריכים
לטפל באופן שונה בהוספה, עדכון מלא ובעדכון חלקי מבחינת מה מותר ומה אסור כי לפעמים יש שדה חובה כאן ולא כאן וכדומה אז אנחנו רוצים לבצע פה כל מיני מקרים כאלה של בדיקות ולידציה והנקודה היא שאקספרס לא מכילה בתוכה את כל המנגנון של הוולידציה וזה בכוונה כי אקספרס נותנת לנו את המנגנון הבסיסי שמאפשר להרים restful
סרוויס לאוויר נותנת עוד כמה דברים מעבר לזה שאנחנו נסתכל בהמשך אבל כל מיני דברים שהם יותר קשורים ללוגיקה ולחישובים הוציאו החוצה לכל מיני פאקג'ים אחרים שאם אנחנו רוצים אנחנו מוסיפים אותם.
אז יש כמובן כל מיני פאקג'ים שמאפשרים לנו לבצע פעולות נלוות כגון ולידציה אחד הנפוצים של בהם זה פאקג' שנקרא JOI אז אנחנו רוצים כרגע לבצע ולידציה עם הפאקג' הזה. אם אתם רוצים לבצע עם פאקאג' אחר שמצאתם, מעולה, לקרוא את הדוקומנטציה שלו ולבצע את זה. אז בואו נתקין קודם כל npm i-joy.ioi והפאקאג' הזה, המטרה שלו זה אחת ויחידה: לבצע ולידציה לא
בהכרח עבור אקספרס, ולבצע ולידציה על מידע. אז הנה, התקנו אותו, אנחנו רואים את הגרסה שהיא כרגע 1431 בתוך הפאקאג', אנחנו רואים שמעבר לאקספרס יש לנו את הג'וי, מעולה, בואו נסגור ונראה איך אנחנו משתמשים בג'וי בכדי לבצע ולידציה, כאשר אנחנו מתחילים עם פוסט.
אחרי זה נעבור לפוט ולפאץ' ולכל ה-IDs האלה שאנחנו רוצים גם כן לבדוק, אבל נתחיל עם ולידציה הכי פשוטה, פוסט ריקווסט, יוזר רוצה להוסיף מוצר, הוא חייב לתת לי שם, וגם יש כל מיני אילוצים לגבי השם, הוא חייב לתת לי מחיר, ויש אילוצים לגבי המחיר, וכמות במלאי, ויש אילוצים לגבי הכמות במלאי.
איפה אנחנו עושים את הוולידציה? הוולידציה מתבצעת במודל, וזאת עוד סיבה טובה למה אנחנו צריכים להשתמש במודל. אז יש לנו כאן את המודל, והדבר הנכון לעשות זה ולידציה במודל עצמו.
הוולידציה הראשונה שאנחנו רוצים לעשות היא ולידציה של פוסט, אז בואו נבנה פה פונקציה validatePost. אם כל הוולידציות שאנחנו עושים הן היו זהות ל-post, patch ו-delete, אז הייתי פשוט כותב פה פונקציה שנקראת validate ורק מבצעת בדיקה שהערכים האלה חוקיים.
בגלל שיש לנו פה כמה ולידציות שונות, אז אנחנו הולכים לכתוב כמה פונקציות שונות. נתחיל עם validatePost. אז דבר ראשון, מה שאנחנו רוצים לעשות זה להביא לעצמנו פה את join.
ג'וי זה קלאס אז לכן אנחנו מתחילים אותו עם עוד גדולה. RequireJoy והדבר הראשון שאנחנו צריכים לבצע זה להחליט מה בעצם חוקי מבחינתנו עבור כל אחד מהמשתנים של הקלאס כאשר ג'וי מספקת לנו את האילוצים לגבי מה כל אחד מהם חובה שיהיה לו.
אז בואו נתחיל. אנחנו בעצם צריכים לבנות משהו שנקרא ולידיישן סכמה. בואו נגדיר כאן קונסט ולידיישן סכמה.
ולידיישן סכמה זה אובייקט, ליטרל אובייקט שאנחנו יוצרים ואנחנו מגדירים מה הפרמטרים שקיימים באובייקט הזה. באובייקט הזה יש איי-די, יש לו name, יש לו price ויש לו stock.
בדיוק אותם משתנים שקיימים לנו כאן. אנחנו רוצים לגבי כל אחד מהם להגיד מבחינתנו מה חוקי ומה לא חוקי רק ביצירה של הסכמה. קודם כל אנחנו צריכים סכמה ורק אחר כך אנחנו משתמשים בסכמה הזאת בשביל לבדוק האם המידע עומד בסכמה או לא עומד בסכמה.
אז כל אחד מהם מה נכון ומה לא נכון ואני מזכיר לכם עבור פוסט. אז רגע, עבור פוסט היוזר בכלל לא צריך להביא לי איי-די.
זה הגיוני כאילו לעשות דבר כזה. אין לי צורך ב-ID כאשר אני עושה פוסט ריקווסט, היוזר בכלל לא שולח לי ID, אבל אם אנחנו לא נעשה ID אז ולידציה של ג'וי תכשיל אותנו ותגיד לנו שאין לך ID אז אתה כבר נופל בוולידציה של מוצר כי למוצר יש ID. כלומר אובייקט מוצר מכיל ID אפילו שה-ID הוא undefined,
אנחנו יכולים לראות את זה כאן כאשר אנחנו יוצרים פוסט ריקווסט כאשר היוזר שולח פוסט ריקווסט אנחנו יוצרים אובייקט מסוג פרודקט ואובייקט מסוג פרודקט מה לעשות גם אם אנחנו לא מקבלים שום ID מהיוזר עדיין הוא מכיל ID שיש לו undefined אז ג'וי תכשיל אותנו ותגיד לנו רגע רגע אתה רוצה לעשות ולידציה למוצר ואמרת לי שאין לו ID אז למה יש לו ID אפילו
שיש לו undefined לכן אנחנו כן אומרים לו משהו לגבי ה-ID אפילו שהיוזר לא מביא לנו את ה-ID. זאת אומרת שההגדרה שאנחנו ניתן לו היא לא תהיה ID שהוא Required מה שנקרא, אבל כן תהיה לי הגדרה של ה-ID.
אז מה אנחנו צריכים לעשות? in a joy הקלאס שהגדרנו פה למעלה, נקודה, ומפה מתחילה להיות לנו סדרה של פונקציות של מה חוקי לגבי אותו משתנה, כרגע זה ID. אז הדבר הראשון אנחנו צריכים להגדיר תמיד מה הסוג שלו.
ID זה number, וזאת פונקציה. הפונקציות האלה משורשרות לפונקציות אחרות. הדבר הבא שאנחנו רוצים להגדיר זה בוא נניח מה הערך המינימלי שלו, מינימום.
אבל האמת בפוסט אין לנו בכלל צורך ב-ID ולכן לא אפילו נגדיר מינימום. אז כרגע יש לנו את הדבר הכי בסיסי שאנחנו יכולים להגיד לו ש-Joy ש-ID זה רק מספר, זה הכל.
מה אנחנו צריכים להגדיר ב-Name? אז אנחנו אומרים לו ש-Joy Name זה סטרינג. זה הדבר הראשון, תמיד זה קודם כל הטיפוס נתונים שחייב להיות.
הדבר הבא, Require. אנחנו חייבים שיהיה לנו שם. אחר כך, כמה מינימום תווים, בגלל שאנחנו סטרינג, אז המינימום מתייחס לתווים, כמה מינימום תווים אנחנו מאשרים ש-Name יהיה.
כלומר, מחייבים ש-Name יהיה. בואו נניח שלושה תווים. כרגע יש לנו את ההגדרות של name. בואו נלך רגע ל-price, פרייס זה number ואנחנו מחייבים שהמינימום שיהיה לו זה 0.
בגלל שהגדרנו שהוא number אז הוא 0. רגע בואו אפילו נעשה required, נגיד שהוא שדה חובה. ובואו נעשה את אותו הדבר, האמת אולי נוסיף גם מקסימום, יאללה בואו נתפרע.
מקסימום של תווים, סליחה של המספר של הפרייס בוא ניתן לו 1000. הגדרה סתם זרקתי כאן ופה ניתן לו max יותר מ-100 תווים אתה לא יכול לשלוח לי שם לא רוצה שהוא יפציץ לי את הדאטאבייס בואו נשכפל את זה בדיוק אותו הדבר נגיד שזה הסטוק שלנו ניפטר מזה ומהפסיק ונגיד שהמקסימום בסטוק זה 10,000 משהו קצת שונה אז אנחנו רואים שגם ה-name גם הפרייס וגם הסטוק הם
מוסדות חובה, name הוא בין שלושה תווים למאה תווים, price הוא בין אפס לאלף ו-stock הוא בין אפס לעשר אלף. הנה יש לנו פה את ההגדרות המתאימות עבור הוולידציה של הפוסט.
עד כאן הכל בסדר. מה אנחנו עושים עם האובייקט הזה? אז מה שאנחנו רוצים לעשות עם האובייקט הזה זה להתחיל לבדוק האם האובייקט הנוכחי שלנו, כי אנחנו הרי קלאס מוצרים מהקלאס פה אובייקט.
אז האם האובייקט שמכיל i,d,name,price ו-stock עומד בסכמה הזאת שכרגע רק יצרנו אותה אבל לא השתמשנו איתה? אז בואו נמשיך ויש לנו joy.validate.
פונקציית validate של joy אומרת לי תשמע, תן לי את האובייקט שאתה רוצה שאני אבדוק. איזה אובייקט אתה רוצה? לא את הסכמה, את האובייקט. אני רוצה לבדוק את האובייקט הנוכחי שיצרו ממני, מהקלאס.
זה כמובן יהיה this. אני רוצה שתבדוק אותי האובייקט שלנו יש לו ID name price ו-stock מול איזה סכמה אתה רוצה שאני אבדוק את זה? שום בעיה ולידיישן סכמה בבקשה יצרנו פה סכמה אז קודם כל זה הכי הכי סימפל תכף נשדרג פה כמה דברים עכשיו כל הסיפור הזה מחזיר לנו ריזולט תוצאה של הוולידציה בואו ניגש ונראה מה אנחנו עושים עם הריזולט אם בריזולט יש משתנה שנקרא error שימו
אני חושב שה-error הוא ביחיד, זה טיפה מבלבל, אבל הוא מכיל את כל השגיאות שיכולות להיות. זה טיפה מבלבל, error הוא אובייקט יחיד, אבל בתוכו יש כל שגיאה שיכולה להתבצע.
אז יכול להיות שיש בו הרבה שגיאות. אז אם קיים בתוך ה-result אובייקט error זה אומר שהייתה שגיאה. אם לא קיים אז error יהיה undefined ואז אנחנו לא ניכנס לתוך ה-if הזה.
ואם קיימת שגיאה אנחנו רוצים להחזיר את