ToCode
الذهاب إلى القناة على Telegram
1 421
المشتركون
+224 ساعات
+17 أيام
+130 أيام
أرشيف المشاركات
1 421
סך הכל מאוד אהבתי את הפרויקט ואם אתם מתחילים פרויקט ריאקט חדש בקרוב אני ממליץ לבדוק אותו בתור תחליף מעניין ל create-react-app.
1 421
אחרי שראינו איך להשתמש ב Next כדי לבנות אתר סטטי בואו נמשיך לראות איך להשתמש בו כדי לבנות אתר דינמי עם Server Side Rendering ו Client Side Router. האמת שזה די פשוט.
בתיקיית
pages יש לנו בינתיים דף אחד בקובץ index.js. כל קובץ שאנחנו יוצרים שם מייצג דף נוסף באתר, ובאופן אוטומטי מקבל חיבור ל Router. ניצור קובץ נוסף באותה תיקיה בשם about.js ובו התוכן הבא:
import Head from 'next/head'
import Link from 'next/link'
export default function About() {
return (
<div>
<Head>
<title>About Us</title>
<meta name="description" content="Generated by create next app" />
<link rel="icon" href="/favicon.ico" />
</Head>
<main>
<h1>About Us</h1>
<p>
Next.JS is actually a cool project.
<Link href="/">Back Home</Link>
</p>
</main>
</div>
)
}
ובקובץ index.js הוסיפו איפה שתרצו את הלינק לדף האודות:
<Link href="/about">About Us</Link>
הפעלה מחדש במצב פיתוח עם yarn dev תאפשר לנו לעבור בין הדפים או לטעון כל אחד מהם בנפרד. במצב ייצור כל נתיב נשמר בקובץ js משלו ובצורה אוטומטית רק במעבר בין דפים ייטען הקוד של הדפים הפנימיים (מה שנקרא Code Splitting). אם תלחצו על View Page Source בדפדפן תוכלו לראות שמקור הדף הוא HTML מלא. זה בעצם אותו הדף שרונדר בשלב הבניה של הפרויקט.
לנקסט יש מנגנון שמאפשר הרצת קוד צד-שרת עם כל בקשה נכנסת ורינדור העמוד בשרת בצורה דינמית באמצעות פונקציה בשם getServerSideProps. אפשר לקרוא עליה בתיעוד כאן:
https://nextjs.org/docs/basic-features/data-fetching#getserversideprops-server-side-rendering.
## פיתוח API Endpoint
ה Use Case השלישי של נקסט הוא הקמת Backend for Frontend, כלומר שרת Node.JS חביב שנכתב יחד עם האפליקציה שלנו ותפקידו למשוך מידע ממערכות ישנות ולחבר מספר מקורות מידע שונים כדי שיהיה לי קל לכתוב את קוד ה Front End.
ב Next אני בונה API Endpoints כאלה באמצעות יצירת קבצים בתיקיית pages/api. נראה את קובץ הדוגמה שנמצא שם כבר בשם pages/api/hello.js:
// Next.js API route support: https://nextjs.org/docs/api-routes/introduction
export default function handler(req, res) {
res.status(200).json({ name: 'John Doe' })
}
הקובץ מייצא פונקציה בודדת בשם handler המקבלת אוביקט Request ו Response ושולחת אוביקט JSON ללקוח.
בואו נעדכן את דף ה"אודות" שיצרנו כך שימשוך את המידע מה API הזה. קודם כל אני מוסיף לפרויקט את swr עם:
$ yarn add swr
ונעדכן את הקוד בקובץ pages/about.js לתוכן הבא:
import Head from 'next/head'
import Link from 'next/link'
import useSWR from 'swr'
const fetcher = (...args) => fetch(...args).then(res => res.json())
export default function About() {
const { data, error } = useSWR('/api/hello', fetcher)
const name = data ? data.name : undefined;
return (
<div>
<Head>
<title>About Us</title>
<meta name="description" content="Generated by create next app" />
<link rel="icon" href="/favicon.ico" />
</Head>
<main>
<h1>About Us</h1>
{name && <h2>Hello {name}</h2>}
<p>
Next.JS is actually a cool project.
<Link href="/">Back Home</Link>
</p>
</main>
</div>
)
}
שימו לב לשורה:
const { data, error } = useSWR('/api/hello', fetcher)
באופן אוטומטי יש לנו נתיב בצד השרת שמתאים לקובץ api/hello.js, שנטען מאותו Origin כך שלא צריך מדיניות CORS ומריץ את הפונקציה handler.
יש להם גם תמיכה מלאה בנתיבים דינמיים ופרמטרים ואפשר לקרוא על זה בתיעוד כאן:
https://nextjs.org/docs/api-routes/dynamic-api-routes.
## דעתי על הפרויקט
נקסט הוא פרויקט גדול עם המון יכולות והמון פינוקים קטנים. בעבודה איתו עבור ה Use Cases שתיארתי בפוסט כמעט לא בזבזתי זמן על חיפוש פיתרונות ולא ראיתי מקומות בהם נקסט הכריח אותי לעבוד בצורה מסוימת או חסם אותי כך שלא יכולתי לפתור בעיה בצורה שרציתי.1 421
className={styles.card}
>
<h2>Deploy →</h2>
<p>
Instantly deploy your Next.js site to a public URL with Vercel.
</p>
</a>
</div>
</main>
<footer className={styles.footer}>
<a
href="https://vercel.com?utm_source=create-next-app&utm_medium=default-template&utm_campaign=create-next-app"
target="_blank"
rel="noopener noreferrer"
>
Powered by{' '}
<span className={styles.logo}>
<Image src="/vercel.svg" alt="Vercel Logo" width={72} height={16} />
</span>
</a>
</footer>
</div>
)
}
הפרויקט כבר כולל מערכת הגדרות וובפאק די מורכבת שכרגיל מוחבאת מאיתנו. אנחנו יכולים להוסיף הגדרות משלנו לקובץ next.config.js, למשל בשביל להוסיף Loader-ים. בין הדברים שכבר קיבלנו מהקופסא אפשר למצוא את התמיכה ב CSS Modules, טעינת קבצי CSS ותמיכה ב Scss.
לפני שנמשיך לבנות עוד דפים בואו נראה איך לייצא את מה שכבר יש לנו לתיקיית out כדי לקבל אתר סטטי. נקסט מגיע עם מנגנון לאופטימיזציה של תמונות באמצעות הקומפוננטה Image, אבל מגננון זה בברירת מחדל לא נתמך באתרים סטטיים (יש להם כמה וורקאראונדים אבל לא ניכנס לזה כאן), לכן קודם כל נחליף את Image ב img רגיל בקובץ pages/index.js ונקבל בקובץ את התוכן הבא:
import Head from 'next/head'
import styles from '../styles/Home.module.css'
export default function Home() {
return (
<div className={styles.container}>
<Head>
<title>Create Next App</title>
<meta name="description" content="Generated by create next app" />
<link rel="icon" href="/favicon.ico" />
</Head>
<main className={styles.main}>
<h1 className={styles.title}>
Welcome to <a href="https://nextjs.org">Next.js!</a>
</h1>
<p className={styles.description}>
Get started by editing{' '}
<code className={styles.code}>pages/index.js</code>
</p>
<div className={styles.grid}>
<a href="https://nextjs.org/docs" className={styles.card}>
<h2>Documentation →</h2>
<p>Find in-depth information about Next.js features and API.</p>
</a>
<a href="https://nextjs.org/learn" className={styles.card}>
<h2>Learn →</h2>
<p>Learn about Next.js in an interactive course with quizzes!</p>
</a>
<a
href="https://github.com/vercel/next.js/tree/master/examples"
className={styles.card}
>
<h2>Examples →</h2>
<p>Discover and deploy boilerplate example Next.js projects.</p>
</a>
<a
href="https://vercel.com/new?utm_source=create-next-app&utm_medium=default-template&utm_campaign=create-next-app"
className={styles.card}
>
<h2>Deploy →</h2>
<p>
Instantly deploy your Next.js site to a public URL with Vercel.
</p>
</a>
</div>
</main>
<footer className={styles.footer}>
<a
href="https://vercel.com?utm_source=create-next-app&utm_medium=default-template&utm_campaign=create-next-app"
target="_blank"
rel="noopener noreferrer"
>
Powered by{' '}
<span className={styles.logo}>
<img src="/vercel.svg" alt="Vercel Logo" width={72} height={16} />
</span>
</a>
</footer>
</div>
)
}
לצערי זה לא מספיק כי נקסט ממש רוצים שנשתמש באחד ממנגנוני אופטימיזציית התמונות שלהם, אז צריך גם לעדכן את הקובץ .eslintrc לתוכן הבא:
{
"extends": ["next", "next/core-web-vitals"],
"rules": {
"@next/next/no-img-element": "off",
}
}
ועכשיו אפשר להיכנס לתיקיית הפרויקט ולהפעיל:
$ npx next build && npx next export
ולקבל בתיקיית out את כל הפרויקט בתור קבצים סטטיים.
## מערכת הניתובים1 421
# מבוא זריז ל Next.JS
אחד הפרויקטים המעניינים והפופולריים בעולם של React היום הוא Next.JS. הפרויקט מציע פריימוורק לפיתוח קוד Front End ו Back End משולבים ומטפל בשבילנו באינטגרציה בין השניים. בואו נראה איך זה עובד ומתי כדאי להשתמש בו.
## מה זה Next.JS
נקסט הוא משהו בין אוסף כלים לפריימוורק שעוזר לפתח יישומי React הכוללים רכיב של Backend for Front End, כלומר בנוסף לקוד צד הלקוח הרגיל יש לנו גם קוד צד שרת שאחראי בעיקר על תקשורת ושליפת מידע מיישום או יישומים גדולים יותר.
נדמיין מערכת שחושפת כבר מספר API Endpoints או אולי אפילו מספר מערכות קיימות, ועכשיו אנחנו רוצים להוסיף ממשק ריאקטי למערכת זו. למרות שאני יכול להשתמש ב JavaScript בצד לקוח כדי למשוך את כל המידע שאני רוצה מהמערכות הישנות, יכול להיות שזה יוביל להרבה בקשות Ajax. שימוש בשרת Node.JS קטן שיפנה לכל המערכות הישנות ובמכה אחת יוציא את כל המידע וישלח אותו לריאקט יכול לשפר ביצועים בצורה משמעותית.
ייתרון נוסף של הקמת Node.JS Backend היא התמיכה ב Server Side Rendering. מנגנון מובנה בפריימוורק מאפשר לשרת להחזיר ללקוחות קוד HTML מוכן להצגה במקום קוד JavaScript וכך לשפר את חווית המשתמש וגם לשפר את הניראות במנועי חיפוש.
יכולת נוספת מעניינת של נקסט היא מנגנון ה Build לפרויקט. מנגנון זה יכול לייצר אתר סטטי מתוך קוד React. המנגנון מגיע עם יכולת להריץ קוד שלנו בזמן הבניה, וכך אפשר לקחת לדוגמה אתר וורדפרס שלם ולהפוך אותו לאתר סטטי, כלומר לבטל את התלות בבסיס הנתונים.
סך הכל Next יעזור לנו לבנות אתר ריאקט באחד או יותר מהתרחישים הבאים:
1. כשאנחנו רוצים לבנות אתר סטטי לגמרי אבל תוך שימוש ב React ואפשרות להריץ קוד JavaScript בזמן הבניה.
2. כשאנחנו רוצים לבנות אתר צד-לקוח שמתממשק עם שרת Node.JS ומחפשים מנגנון לשיתוף קוד פשוט בין השניים.
3. כשאנחנו רוצים לבנות אתר React עם Server Side Rendering.
## מבנה פרויקט
בשביל להתחיל פרויקט נקסט מפעילים את הפקודה הבאה:
$ npx create-next-app <app_name>
לדוגמה אם שם האפליקציה שלי הוא frontend אני מפעיל:
$ npx create-next-app frontend
הפקודה יוצרת תיקיה בשם frontend ובתוכה התיקיות:
.
├── next.config.js
├── package.json
├── pages
│ ├── api
│ │ └── hello.js
│ ├── _app.js
│ └── index.js
├── public
│ ├── favicon.ico
│ └── vercel.svg
├── README.md
├── styles
│ ├── globals.css
│ └── Home.module.css
└── yarn.lock
בשביל להריץ את הפרויקט במצב פיתוח מפעילים:
$ yarn dev
הקוד לסטארטר מתחיל בקובץ pages/index.js. אתם יכולים להיכנס ולשנות אותו ולראות על המסך בלייב את העדכונים שלכם.
זה קוד הסטארטר כמו שנוצר אצלי:
import Head from 'next/head'
import Image from 'next/image'
import styles from '../styles/Home.module.css'
export default function Home() {
return (
<div className={styles.container}>
<Head>
<title>Create Next App</title>
<meta name="description" content="Generated by create next app" />
<link rel="icon" href="/favicon.ico" />
</Head>
<main className={styles.main}>
<h1 className={styles.title}>
Welcome to <a href="https://nextjs.org">Next.js!</a>
</h1>
<p className={styles.description}>
Get started by editing{' '}
<code className={styles.code}>pages/index.js</code>
</p>
<div className={styles.grid}>
<a href="https://nextjs.org/docs" className={styles.card}>
<h2>Documentation →</h2>
<p>Find in-depth information about Next.js features and API.</p>
</a>
<a href="https://nextjs.org/learn" className={styles.card}>
<h2>Learn →</h2>
<p>Learn about Next.js in an interactive course with quizzes!</p>
</a>
<a
href="https://github.com/vercel/next.js/tree/master/examples"
className={styles.card}
>
<h2>Examples →</h2>
<p>Discover and deploy boilerplate example Next.js projects.</p>
</a>
<a
href="https://vercel.com/new?utm_source=create-next-app&utm_medium=default-template&utm_campaign=create-next-app"1 421
# עשר עצות להתנהגות מקצועית כלפי לקוחות (טיפ פרילאנס)
לקוחות טובים הם מה שנותן לנו כח ליצור ולתת את העבודה הטובה ביותר שלנו, ולקוחות טובים נוטים להעדיף עבודה עם פרילאנסרים מקצועיים. הנה 10 עצות פשוטות שיעזרו לכם למשוך ולשמר לקוחות טובים יותר:
1. היו ברורים לגבי הצעת הערך שאתם נותנים ותנו תוצאה טובה יותר ממה שהלקוח ציפה.
2. שימו את הרגשות בצד. את הלקוח לא מעניין כמה קשה לכם או שקמתם על צד שמאל הבוקר. אתם פה בשביל לעבוד.
3. הקשיבו לבעיה האמיתית של הלקוח, לפני שתציעו את הפיתרונות שאתם כבר מכירים.
4. היו מוכנים להשתנות ולנסות דברים חדשים, אם זה מה שצריך בשביל לבצע את העבודה.
5. היו מוכנים להתעלם מרעשי רקע, כדי להגיע לסוף עם מוצר עובד.
6. היו פתוחים לגבי הקשיים אבל אל תפילו אותם על הלקוח.
7. אל תפחדו להיות כנים גם לגבי טעויות או דברים שניסיתם ולא עבדו.
8. היו פתוחים לגבי המדדים, והיו מוכנים לדבר עליהם. מה אומרת "הצלחה" בשבילכם? מה אומרת "הצלחה" בשביל הלקוח?
9. כשאתם לא יכולים לעזור יותר, הסבירו למה ואל תפחדו לעזוב את הפרויקט.
10. הקדימו את הזמנים.
הכלל בפרילאנס: "אתה תשלם הרבה ותקבל ערך גדול בצורה משמעותית ממה ששילמת עבורו". פרילאנסרים טובים הם אלה שיסתכלו על בעיה בתור הזדמנות, וכמה שהיא יותר קשה כך המוטיבציה עולה בהתאם.
1 421
# עשר עצות להתנהגות מקצועית כלפי לקוחות (טיפ פרילאנס)
לקוחות טובים הם מה שנותן לנו כח ליצור ולתת את העבודה הטובה ביותר שלנו, ולקוחות טובים נוטים להעדיף עבודה עם פרילאנסרים מקצועיים. הנה 10 עצות פשוטות שיעזרו לכם למשוך ולשמר לקוחות טובים יותר:
1. היו ברורים לגבי הצעת הערך שאתם נותנים ותנו תוצאה טובה יותר ממה שהלקוח ציפה.
2. שימו את הרגשות בצד. את הלקוח לא מעניין כמה קשה לכם או שקמתם על צד שמאל הבוקר. אתם פה בשביל לעבוד.
3. הקשיבו לבעיה האמיתית של הלקוח, לפני שתציעו את הפיתרונות שאתם כבר מכירים.
4. היו מוכנים להשתנות ולנסות דברים חדשים, אם זה מה שצריך בשביל לבצע את העבודה.
5. היו מוכנים להתעלם מרעשי רקע, כדי להגיע לסוף עם מוצר עובד.
6. היו פתוחים לגבי הקשיים אבל אל תפילו אותם על הלקוח.
7. אל תפחדו להיות כנים גם לגבי טעויות או דברים שניסיתם ולא עבדו.
8. היו פתוחים לגבי המדדים, והיו מוכנים לדבר עליהם. מה אומרת "הצלחה" בשבילכם? מה אומרת "הצלחה" בשביל הלקוח?
9. כשאתם לא יכולים לעזור יותר, הסבירו למה ואל תפחדו לעזוב את הפרויקט.
10. הקדימו את הזמנים.
הכלל בפרילאנס: "אתה תשלם הרבה ותקבל ערך גדול בצורה משמעותית ממה ששילמת עבורו". פרילאנסרים טובים הם אלה שיסתכלו על בעיה בתור הזדמנות, וכמה שהיא יותר קשה כך המוטיבציה עולה בהתאם.
1 421
# לא סתם קוראים לזה "החלק הקשה"
הדבר הראשון שהופך את החלק הקשה בפרויקט לקשה הוא החלק הקשה עצמו. אם צריך ללמוד כלי חדש, אז באמת יש המון מידע שצריך להבין ולהטמיע, יש תרגול שצריך לבצע, יש האטה בעבודה ואולי צריך בתקופת הלימוד להשקיע יותר שעות. זה באמת יותר קשה מאשר להמשיך להשתמש בכלי הישן.
אבל מה שבאמת הופך את החלק הקשה לקשה זה אנחנו. אלה הרגשות שלנו שאנחנו מלבישים על הסיטואציה והופכים אותה מסתם סיטואציה שדורשת יותר עבודה לסיטואציה "קשה". בלימוד כלי חדש, זה יהיה הפחד שאולי אף פעם לא אהיה טוב בו כמו שאני טוב בכלי שאני היום משתמש בו; אולי התסכול כשאני יושב יום שלם על קוד שבכלי הקודם הייתי כותב בכמה דקות; אולי תחושת האובדן על כל השעות שכבר השקעתי בלימוד הכלי שאני עכשיו מכיר, וממנו אצטרך להיפרד. אלה הרגשות שמלווים ומעכבים את תהליך הלימוד והופכים אותו למאבק בשתי חזיתות: גם ההתמודדות עם הקושי האמיתי, וגם ההתמודדות עם אותם רגשות שלא עוזבים.
לא סתם קוראים לזה "החלק הקשה" בפרויקט. ואם אנחנו רוצים להתקדם החלק הקשה חייב להיות שם, בלעדיו אין לימוד, אין התמודדות ואין צמיחה. החלק הקשה הוא קשה מספיק, והמשימה החשובה שלנו היא לחלק את ההתמודדות. לשבת ללמוד כאילו אין פחד, אין תסכול ואין אובדן, ובמקביל לתת לרגשות את המקום שלהם מחוץ לזמן הלימוד ובלי ליצור הסחות דעת. קשה? ברור. בשביל זה באנו.
1 421
# הזמנה לוובינר: בדיקות בפרודקשן
איזה חיים נפלאים היו לנו פעם... בן אדם כותב מערכת, בודק את הגירסה ומעלה לפרודקשן. אחר כך יכול לכתוב גירסה חדשה, לבדוק את הגירסה החדשה ושוב להעלות לפרודקשן.
אחר כך הגיעו בדיקות אוטומטיות ו CI ובכלל היינו בגן עדן: במקום להעסיק אנשי QA יקרים שיעשו את אותו דבר שוב ושוב, כתבנו סקריפטים של בדיקות ונתנו לשרת ה CI/CD להריץ את כל הבדיקות ולזרוק לפרודקשן את הקוד שעבר.
אבל אז הגיעו Micro Services וריסקו את הכל. בעולם ה Micro Services החדש שלנו אני לא יכול לבדוק את הגירסה כי אין לי מושג מהי הגירסה. כל גירסה מורכבת מעשרות או מאות סרביסים, שכל אחד מהם מתעדכן 7 פעמים ביום (כי הם קטנים ואפשר). הבדיקות האוטומטיות על שרת נפרד בסביבת פיתוח הפכו לחלום רחוק על דברים פשוטים שהיו פעם ולא יחזרו.
היום בנוסף לבדיקות יחידה ובדיקות מקצה לקצה בסביבת פיתוח אנחנו צריכים משהו נוסף, אנחנו צריכים דרך לגלות שאחד הסרביסים שהעלינו שבר את המערכת לפני שמשתמשים יראו את הבעיה, ואנחנו צריכים לראות שדברים עובדים על נתונים אמיתיים ועם כל הסביבה האמיתית שמשתמשים רואים. וכך נולד הקונספט המזעזע של Testing In Production. כתיבת סט בדיקות מקצה לקצה שירוצו באופן אוטומטי עם כל Deployment של כל סרביס, על סביבת הפרודקשן כדי לוודא שלא שברנו כלום.
החסרונות של השיטה ברורים:
1. הבדיקה יוצרת עוד עומס על השרת, במקום לפנות אותו כדי לעזור למשתמשים אמיתיים.
2. הבדיקה עלולה בעצמה לשבור משהו בבסיס הנתונים או בשרת.
3. הבדיקה מגלה את הבעיה מאוחר מדי, אחרי ה Deployment במקום לפניו.
4. הבדיקה לא יכולה "לרמות", כלומר להכניס נתונים ספציפיים למערכת כדי לקבל תוצאה צפויה.
אבל לצידם יש שני יתרונות חשובים שלא היו לנו בבדיקות בסביבת פיתוח: הראשון הוא האמינות הגבוהה יותר, מאחר ועובדים על נתונים אמיתיים; השני הוא הניתוק המוחלט בין קוד הבדיקות לקוד המערכת. הבדיקות רצות בתור סרביס נפרד ואי אפשר להתבסס על שום ידע פנימי בעת כתיבתן.
מחר בעשר בבוקר אני וגבור סבו נעביר וובינר (באנגלית הפעם, כי גם לי מתחשק לגוון) על כתיבת בדיקות לאתר קיים והרצתן בסביבת פרודקשן. אנחנו מתכננים לקחת את אתר meetup.com, לבנות עבורו תוכנית בדיקות ולממש כמה שנספיק ממנה, וכמובן להריץ את הבדיקות משרת בדיקות נפרד דרך Github Actions. אם בא לכם להצטרף כצופים או לעזור לנו בכתיבה מוזמנים להירשם בקישור:
https://code-maven.com/selenium-with-python-live.
הקלטה תפורסם גם כאן וגם ביוטיוב של גבור כמה ימים אחרי המפגש.
נתראה,
ינון.
1 421
# מה זה API Gateway והאם גם אני צריך אחד
מערכת המפותחת בגישה של Micro Services בנויה מסרביסים קטנים ועצמאיים. במערכת כזאת עוזר לפעמים לבנות סרביס אחד שיחבר בין הסרביסים השונים ויהיה סוג של דלת כניסה למערכת. לסרביס כזה אנחנו קוראים API Gateway.
בשביל להבין איך API Gateway מתפקד או למה צריך אותו, בואו נדמיין מערכת Micro Services של חנות דיגיטלית. במערכת יכולים להיות לנו הסרביסים הבאים:
1. סרביס קטלוג מוצרים, בו מנהל מערכת יכול לעדכן פרטים על המוצרים השונים בחנות והמלאי שלהם.
2. סרביס ניהול פרופילים לקונים, שאחראי על טיפול במשתמשי האתר ושמירת המידע שלהם.
3. סרביס הזמנות ותשלומים.
4. סרביס המלצות, שאחראי על חיבור מידע ממספר מקורות כדי ליצור המלצות מותאמות אישית לגולשים.
5. סרביס סטטיסטיקות שאחראי על איסוף סטטיסטיקות של תנועה באתר כדי לעזור ל Product לשפר את המערכת.
בתוך מערכת כזאת אפשר לדמיין קוד Front End שאחראי להצגת דף הבית של גולש שחוזר לאתר אחרי שכבר קנה מוצרים בעבר:
1. הוא יצטרך לתקשר עם סרביס קטלוג המוצרים כדי לזהות איזה מוצרים "מקודמים" ומופיעים עכשיו בדף הבית.
2. הוא יצטרך לתקשר עם סרביס ההמלצות, כדי לראות אם יש המלצות אישיות לאותו גולש.
3. הוא יצטרך לתקשר עם סרביס הפרופילים, כדי להציג לגולש את תמונת הפרופיל שלו בצד של המסך.
4. הוא יצטרך לתקשר עם סרביס הסטטיסטיקות כל פעם שמשתמש מבצע פעולה באתר.
שמירת הכתובות של כל הסרביסים השונים בקוד JavaScript עשויה להיות מסורבלת. ואם נצטרך לשנות את הכתובות נצטרך בהתאמה גם להעלות גירסה לקוד צד הלקוח. בנוסף, אם כל סרביס רץ על שרת או פורט שונה, הסרביסים יצטרכו לתאם מדיניות CORS כדי שעוגיות יגיעו מהלקוח בצורה נכונה לכל סרביס, או שקוד צד הלקוח יצטרך לנהל בעצמו גישה באמצעות טוקנים.
אבל אולי הבעיה הכי גדולה היא שקוד צד הלקוח צריך להוציא מספר בקשות HTTP ב Ajax רק בשביל להראות את עמוד הבית. ככל שיש יותר בקשות כך זמן הטעינה גדול יותר ואין לנו שליטה על סדר המידע שמגיע.
גם בצד של הסרביסים ארכיטקטורה כזאת משאירה פערים. התנהגות משותפת למספר סרביסים צריכה להיכתב בתור ספריית קוד ולהיות משולבת בכל סרביס בנפרד. בנוסף כשנסתכל על הלוגים יהיה קשה לזהות שכל הבקשות לכל הסרביסים השונים קשורות לאותו דף שלקוח ספציפי מנסה להציג.
הפיתרון לכל הבעיות נקרא API Gateway. זה לא כלי אלא תבנית פיתוח, ולמעשה יש המון כלים שיכולים לתפקד בתור API Gateway, והרבה פעמים נראה מערכות שמשלבות כמה מהם. בתבנית API Gateway אנחנו בונים שירות בכניסה למערכת שיחבר את כל הסרביסים שלנו, ובגלל זה לפעמים הוא נקרא גם Backend for Frontend.
בדוגמת החנות שלנו אפשר לדמיין API Gateway שיקבל פניה לנתיב /, יפנה לכל הסרביסים במערכת, יאסוף מהם את התשובות שלהם לפניה ויחזיר אוביקט מידע אחד שמורכב מכל התשובות של כל הסרביסים.
אבל יש עוד כמה דברים ש API Gateway יכול לעשות:
1. ה Gateway יוסיף "מזהה בקשה" לכל בקשה שנכנסת למערכת, וכל הסרביסים משתמשים במזהה זה בכתיבה ללוג. כך קל לנו להסתכל בלוג ולהבין איזה בקשות קשורות, גם בין סרביסים שונים.
2. ה Gateway יוכל לטפל ב Caching של תשובות כדי להוריד עומס מהסרביסים הפנימיים.
3. ה Gateway יוכל לטפל ב Rate Limit או לחסום בוטים.
4. אם חלק מהסרביסים למטה, ה Gateway הוא במקום טוב לזהות את זה מהר ולהעביר את העומס לסרביסים אחרים.
5. ה Gateway יוכל לתעדף משתמשים מסוימים באמצעות העברתם לסרביסים פנויים יותר.
רק בגלל שהחלטתם להשתמש ב API Gateway אל תחשבו שאתם נעולים לכלי אחד ספציפי או יחיד במערכת. אין בעיה להרים שרת NGINX או HAProxy בכניסה למערכת כדי לטפל ב Rate Limit, ומאחוריו שרת Express כדי לבצע Request Aggregation. הדבר החשוב הוא להסתכל על ה Gateway בתור סרביס שיכול להיות מורכב מכמה תחנות ואחראי על תחומי עבודה מסוימים.
שימוש ב API Gateway יכול לעזור אפילו אם רק התחלתם לעבוד בגישת Micro Services ויש לכם ממש מעט סרביסים במערכת, והוא ממש הכרחי ככל שמספר הסרביסים עולה ואיתו העומס על המערכת והצורך בתיאום.
1 421
# יותר מדי כלים?
בבחירת כלי או ספרית קוד לפיתרון בעיה אין כמעט דרך לענות על השאלות החשובות באמת: האם הספריה הזאת באמת תפתור לי את הבעיה? האם היא תסתדר עם שיטת העבודה או החשיבה הקיימת שלי? האם היא תמשיך להיות מתוחזקת לאורך זמן? האם יהיו לה תופעות לוואי לא מתועדות שרלוונטיות רק למערכת שלי?
קניתי לפני כמה זמן שעון חכם כי חשבתי שזה יעודד אותי לעשות ספורט. שבועיים אחרי הקניה כבר הבנתי ששעון חכם לא היה מה שהייתי צריך בשביל להתחיל ספורט, ובמקביל שמשהו בקרינה שלו עשה לי כאבי ראש מוזרים כך שלא באמת יכלתי ללכת איתו יותר מכמה שעות. שום חיפוש באינטרנט (ותופתעו כמה חיפשתי לפני הקניה של אותו שעון) לא הכין אותי לשתי התובנות האלה. המידע פשוט אישי מדי, יותר מדי ספציפי לקונטקסט שלי. לאחרים יש בעיות אחרות.
ובכל זאת יש שתי מסקנות שאני משתדל לקחת מסיפור השעון, ועוזרות לי להתמודד עם העולם כל פעם שאני מחפש ספריה או כלי חדש:
1. הכלי הוא בסך הכל כלי. אם הבעיה שלך היא שאתה לא עושה ספורט, כלי לא הולך לתקן את צורת ההתנהגות שלך. עדיף לחפש את הכלי אחרי שיצרת את ההרגלים הנכונים. באנלוגיה לתוכנה, לא הייתי ממליץ למפתחי Object Oriented להתחיל לעבוד עם Cloujre רק בגלל שהם שמעו שתכנות פונקציונאלי זה מדליק. קודם תוותרו על הקלאסים ותתחילו לכתוב קוד פונקציונאלי, ואחר כך חפשו את הכלי שמשפר לכם את החיים בתוך ההרגלים שיצרתם.
2. כשמתחילות תופעות לוואי בלתי צפויות, אין טעם להתכחש להן. אם הוספת שירות Monitoring חדש למערכת ופתאום הכל נהיה איטי, קודם כל תזרוק את המוניטור החדש. יש מספיק כלים ועד כמה שזה מאכזב, לפעמים הכלי שבחרת באמת לא מתאים למערכת הספציפית שלך. עדיף להכיר בזה כמה שיותר מהר ולהמשיך לכלי הבא ברשימה.
1 421
# איך לסגור את האתר בשבת עם Haproxy ו Lua
הפרוקסי (haproxy) היה הפרוקסי החביב עליי פחות או יותר מהרגע הראשון שהתחלתי להשתמש בו וככל שלמדתי עליו יותר כך רק מצאתי יותר דברים לאהוב. המטרה בגדול של haproxy היא לקבל תנועה שמגיעה מהעולם לתוך המערכת שלכם ולנתב אותה לשרתים הפנימיים כך שלא יהיה יותר מדי עומס על שרת ספציפי (מה שנקרא Load Balancing), וגם ובעיקר לזהות מאפיינים של בקשה ולנתב אותה לשרת הפנימי המתאים. הוא מתחרה ב nginx וב envoy ולדעתי הוא פשוט יותר משניהם.
טריק נחמד שאפשר לעשות עם haproxy הוא להרחיב אותו באמצעות Lua. באופן רגיל אנחנו יכולים להשתמש ב ACL-ים כדי לנווט בקשות לשירותים מסוימים לפי תוכן הבקשה, לדוגמה השורה הבאה בקובץ הקונפיגורציה:
http-request deny if { path -i -m beg /api/ } { src 10.0.0.0/16 }
תעצור בקשות שמגיעות מהרשת 10.0.0.0/16 ומיועדות לנתיב שמתחיל ב /api. או השורה הזאת:
redirect scheme https if !{ ssl_fc }
תשלח ללקוח HTTP Redirect אם הוא לא פנה ב HTTPS.
אבל הדבר הגדול באמת הוא שאנחנו יכולים להוסיף פונקציות כמו src ו path בעצמנו באמצעות קוד lua. לדוגמה קוד lua הבא:
core.register_fetches("dow", function(txn)
return os.date("*t").wday
end)
מייצר ל Haproxy פונקציה חדשה בשם dow שמחזירה את היום בשבוע (מתחיל מ-1 ליום ראשון).
עכשיו נניח ששמרתי את קוד ה lua מהדוגמה בקובץ /usr/local/etc/haproxy/dow.lua, ונניח שיש לי שני שרתי אפליקציה על הרשת, אחד בשם web שמציג את התוכן האמיתי שלי והשני בשם closed שמציג דף שאומר שהאתר סגור כעת; אז אני יכול לכתוב את קובץ הגדרות ה haproxy.cfg הבא כדי לסגור את האתר בסופי שבוע:
global
log /dev/log local0
log /dev/log local1 notice
user haproxy
group haproxy
daemon
lua-load /usr/local/etc/haproxy/dow.lua
defaults
log global
mode http
timeout connect 10s
timeout client 30s
timeout server 30s
option httplog
option dontlognull
frontend default
bind :80
use_backend closed if { lua.dow() eq 6 } || { lua.dow() eq 7 }
default_backend web
backend web
server s1 web:80
backend closed
server s1 closed:80
הבלוק המעניין הוא הבלוק frontend ובפרט השורות:
use_backend closed if { lua.dow() eq 6 } || { lua.dow() eq 7 }
default_backend web
הפונקציה lua.dow היא פונקציית ה lua שכתבתי שמחזירה את היום בשבוע, והשורה בבלוג הגלובל:
lua-load /usr/local/etc/haproxy/dow.lua
היא שהיתה אחראית לטעינת קובץ ה lua וציון הנתיב אליו.
متاح الآن! بحث تيليغرام 2025 — أهم رؤى العام 
