קודקודייל
  • קודקודייל
  • מי אתם קודקודייל?
  • קורסים בחינם
  • צרו קשר
  • בניית אתרים
    • וורדפרס
  • נגישות אתרים
  • כל הקטגוריות
    • אנגולר
    • HTML
    • CSS
    • Javascript
    • Typescript
    • NodeJs
    • בלוקציין
  • קודקודייל
  • מי אתם קודקודייל?
  • קורסים בחינם
  • צרו קשר
  • בניית אתרים
    • וורדפרס
  • נגישות אתרים
  • כל הקטגוריות
    • אנגולר
    • HTML
    • CSS
    • Javascript
    • Typescript
    • NodeJs
    • בלוקציין
קודקודייל
  • קודקודייל
  • מי אתם קודקודייל?
  • קורסים בחינם
  • צרו קשר
  • בניית אתרים
    • וורדפרס
  • נגישות אתרים
  • כל הקטגוריות
    • אנגולר
    • HTML
    • CSS
    • Javascript
    • Typescript
    • NodeJs
    • בלוקציין
  • קודקודייל
  • מי אתם קודקודייל?
  • קורסים בחינם
  • צרו קשר
  • בניית אתרים
    • וורדפרס
  • נגישות אתרים
  • כל הקטגוריות
    • אנגולר
    • HTML
    • CSS
    • Javascript
    • Typescript
    • NodeJs
    • בלוקציין
ראשי ♦ nodeJs ♦ מדריך typescript in nodejs express

מדריך typescript in nodejs express

עידן יצחקי 14 ביולי 2023 אין תגובות

בואו נראה איך לחבר את typescript ואת nodejs express ביחד, נוסיף גם את nodemon לעבודה יותר נוחה.

תחילה נדבר בקצרה על היתרון בלעבוד עם TS לעומת עבודה ב-JS.

TS מחייב אותנו לעבוד יותר נכון ומצמצם שגיאות, אם לא ניתן לכל משתנה סוג ANY כמו ב-JS אז נקבל 3 יתרונות חשובים:

  1. intellisense
  2. interfaces
  3. התראות ושגיאות כבר בזמן הכתיבה כאשר המידע והסוג לא תואמים או חסרים

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

לאחר שהתקנו NODEJS על המחשב (במידה שלא אז ניתן לעשות את זה כאן)

תחילה, אנחנו צריכים לעדכן typescript גלובלי על המחשב.

npm i -g typescript // install global

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

בתוך הספריה (C:\nodeTs) נריץ את הפקודה הבאה:

tsc --init // creat tsconfig.json

נכנס ל-tsconfig.json ונפעיל ונשנה את השורת:

"target": "ES6"
"rootDir": "./src"
"outDir": "./dist"
"moduleResolution": "node"

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

עכשיו ניצור ספריה נוספת בשם SRC ובתוכה app.ts .

בשלב זה אין עדיין צורך להכנס לתוך ספרית SRC ואפשר להריץ את הפקודות הבאות מתוך ספרית nodeTs

npm init -y // creat package.json
npm i express // creat node_modules
npm i mongoose // for mongoose module
npm i -D typescript ts-node nodemon @types/node @types/express // for dev only

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

בקובץ package.json נעשה את השינויים הבאים:

"scripts": {
    "start": "node dist/app.js",
    "dev": "nodemon src/app.ts",
    "build": "tsc -p ."
  },

עד לכן עשינו את כל השינויים הדרושים.

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

npm i jsonwebtoken --save // creat Tokens
npm i -D @types/jsonwebtoken // for typescript in dev only

npm i bcrypt // encode passwords
npm i -D @types/bcrypt // for typescript in dev only

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

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

import express from "express";

const app = express();

const port: number = 5000;

console.clear();
console.log('-----------start-----------');

app.use((req, res, next) => {
    res.setHeader(
        "Access-Control-Allow-Origin",
        "*"
    );
    res.setHeader(
        "Access-Control-Allow-Headers",
        "Origin, X-Requested-With, Content-Type, Accept, Authorization"
    )
    res.setHeader(
        "Access-Control-Allow-Methods",
        "GET, POST, PATCH, PUT, DELETE, OPTIONS"
    )
    next();
});

app.listen(port, () => console.log(`ON-LINE ${port}`));

זה הבסיס, ברגע שנריץ את הפקודה npm run dev, השרת שלנו יקשיב בפורט 5000.

כמובן שאם ננסה לגלוש ל- http://localhost:5000 , נקבל תשובה של Cannot GET / . הסיבה היא שלא יצרנו עדיין ראוט שיתן מענה לבקשה.

נקודה נוספת, ניתן להחליף את השורת 10 עד 24 ב-CORES.

נתחיל בליצור ספריה בשם APIS ובתוכה קובץ בשם user.interface.ts

export interface user {
    firstName:string;
    lastName:string;
    age?:number;
}

ניצור קובץ נוסף בשם user.models.ts

import { Schema, model } from "mongoose";
import { IUser } from "./user.interface";

const userSchema = new Schema<IUser>({
    firstName: { type: String, required: true },
    lastName: { type: String, required: true },
    age: { type: Number }
})

export const User = model<IUser>('User', userSchema);

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

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

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

שלב הבא הוא הקונטרולר

import { Request, Response } from "express";
import { User } from "./user.models";

export const getUserInfo = async (req: Request, res: Response) => {
    User.findOne({ _id: req.params.id }).then(info => {
        if (info) {
            res.status(200).json({ message: 'Found', reply: info });
        } else {
            res.status(200).json({ message: 'Not found' });
        }
    }).catch(err => {
        console.error(err);
        res.status(500).json({ message: "Failed to execute" });
    })
}

יצרנו קונטרולר פשוט שמקבל ID , מבצע חיפוש ומחזיר אחת מהאופציות הבאות:

  1. סטטוס 200 עם אובייקט שמחזיק הודעה ותשובה של הנתונים עצמם.
  2. סטטוס 200 עם הודעה שלא נמצא, עדיין מדובר בסטטוס 200 בגלל שהפעולה הצליחה, פשוט המידע לא קיים בבסיס הנתונים.
  3. במידה שהייתה תקלה , בסיס הנתונים לא בשירות או פניה לא תקינה וכו'. חוזר סטטוס 500 עם הודעה של שגיאה.

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

השלב הבא הוא הנתב

זה השלב שאנחנו מחברים את הבקשרה שמגיעה מצד הלקוח לפונקציה שאנחנו רוצים להפעיל

import { Router } from "express";
import { getUserInfo } from "./user.controller";

export const routerUser = Router();

routerUser.get('/user/:id', getUserInfo);

תחילה, זימנו את ה-Router

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

בשורה 4, יצרנו והחצנו משתנה שיכיל את כל הראוטים שניצור ולבסוף נחבר אותו ב-app.ts

בשורה 6 יצרנו ניתוב אחד שהוא GET ומצפה לקבל גם ID, במידה שזה יקרה, תופעל הפונקציה getUserInfo.

במידה שרוצים לבצע פעולות לפני שהפונקציה תופעל, ניתן לשרשר בצורה הבאה:

import { Router } from "express";
import { checkAuth } from "../../middleware/check-auth";
import { fileUpload } from "../../middleware/file-upload";
import { getUserInfo } from "./user.controller";

export const routerUser = Router();

routerUser.get('/user/:id', checkAuth, fileUpload.single('file'), getUserInfo);

שורה 8 במקרה שלנו זו רק דוגמה אבל מה שיקרה זה שפונקציה checkAuth ירוץ ראשון, אחרי זה fileUpload ולבסוף getUserInfo

הגענו לחלק הסופי, וזה החיבור ל-app.ts

נעדכן את הקובץ כך:

import express from "express";
import { routerUser } from "./apis/user.routes";

const app = express();

const port: number = 5000;

console.clear();
console.log('-----------start-----------');

app.use((req, res, next) => {
    res.setHeader(
        "Access-Control-Allow-Origin",
        "*"
    );
    res.setHeader(
        "Access-Control-Allow-Headers",
        "Origin, X-Requested-With, Content-Type, Accept, Authorization"
    )
    res.setHeader(
        "Access-Control-Allow-Methods",
        "GET, POST, PATCH, PUT, DELETE, OPTIONS"
    )
    next();
});

app.use('/api/users',routerUser);

app.listen(port, () => console.log(`ON-LINE ${port}`));

השורה שנוספה היא שורה מספר 27 ושורה 2.

זה כל התהליך.

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

זיכרו את החוליות בשרשרת, app קורא ל-router שקורא ל-middleware אם יש, ואז ל-controller שמשתמש ב-model שמוגדר על פי ה-interface.

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

בהצלחה ⛓

פוסטים קשורים:

מדריך nodeJS Express – חלק 5 – server מדריך nodeJS Express – חלק 2 – controllers מדריך nodeJS Express – חלק 4 – middleware מדריך nodeJS Express – חלק 3 – routes
nodejs typescript

אודות המחבר

עידן יצחקי להציג את כל הפוסטים של עידן יצחקי


« פוסט קודם
פוסט הבא »

השארת תגובה

ביטול

חיפוש באתר
בחירת העורכים
29 בדצמבר 2023 עידן יצחקי

שדה טקסט עשיר עם תמונות

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

1 באוקטובר 2021 עידן יצחקי

איך למשוך דינמית favicon של אתרים אחרים ב-JS

בפוסט זה נראה איך אפשר על פי לינקים בדף למשוך את ה-favicon מהדומיין שלהם באופן דינמי, בדיקה של תקינות התמונה

פופולרי
Javascript functions – היכרות עם סוגי פונקציות
Javascript
21 בדצמבר 2024 אין תגובות
Nested routing in angular standalone component
Typescript
15 בנובמבר 2024 תגובה אחת
בחרו לפי תגיות
angular blockchain css ethers express front-end fullstack GQL html javascript next js nextjs nodejs react hooks reactjs solidity webgl אנגולר בלוקציין וורדפרס לימודי אנגולר לימודי וורדפרס לימוד ריאקט מדריך front-end מדריך GQL מדריך אנגולר מדריך וורדפרס מדריך חינם react מדריך ריאקט מפתח בלוק מפתח בלוקציין מתכנת front-end מתכנת בלוקציין מתכנת פרונט סולידיטי קורס front end קורס fullstack קורס nextjs קורס אנגולר קורס בלוקציין קורס בלוקציין בחינם קורס סולידיטי קורס ריאקט קורס תכנות קורס תכנות בחינם
סינון על פי קטגוריות
CSS fullstack HTML IIS Javascript nodeJs SEO Typescript אנגולר בלוקציין בניית אתרים וורדפרס חיפוש עבודה כלים נוספים כללי נגישות קורסים ריאקט תלת מימד תקלות ופתרונות
צור קשר
כל הזכויות שמורות לקודקודייל
ליצירת קשר: @ קודקודייל
גלילה לראש העמוד