آموزش توسعه‌ی یک برنامه‌ی ساده با Node.js و MongoDB


۸ اردیبهشت ۱۴۰۰
آموزش توسعه‌ی یک برنامه‌ی ساده با node.js و mongoDB

هدف این مقاله باتوجه به عنوان آن کاملا مشخص است اما برای توضیحات بیشتر باید بگوییم که می‌خواهیم یک برنامه‌ی ساده‌ی Todo را با Node.js توسعه دهیم و برای این کار از Mongoose که یک کتابخانه‌ی بسیار محبوب برای اتصال برنامه‌های Node.js به MongoDB است، استفاده خواهیم کرد.

Mongoose چیست؟

Mongoose را می‌توان یک کتابخانه‌ی ODM (Object Data Modeling) برای اتصال برنامه‌های Node.js به دیتابیس MongoDB دانست که با استفاده از آن می‌توانید روابط بین داده‌ها و اعتبارسنجی Schema را مدیریت کنید.

mongoose چیست؟

تفاوت MongoDB و دیتابیس‌های مبتنی‌ بر SQL

MongoDB یک دیتابیس NoSQL است که با مطالعه‌ی مقاله‌ی مقایسه SQL و NoSQL، کدام را انتخاب کنیم؟ می‌توانید اطلاعات بیشتری از تفاوت‌های این دو نوع دیتابیس کسب کنید اما به‌طور کلی، دیتابیس‌های NoSQL بدون Schema یا به‌عبارتی Schema-less هستند. این یعنی شما می‌توانید داده‌های json خود را بدون پیروی از ساختار خاصی در آن ذخیره کنید. افزایش سرعت توسعه‌ی برنامه از دیگر مزایای دیتابیس‌های NoSQL است زیرا پیچیدگی‌های کاری ما را کم‌تر می‌کند.

برای درک بهتر این موضوع‌ها می‌توانید تصویر زیر را مشاهده کنید که یک مثال ساده برای مقایسه‌ی نحوه‌ی ذخیره‌سازی داده‌ها در MongoDB و SQL است.

نحوه‌ی ذخیره سازی داده‌ها در دیتابیس mongodb
نحوه‌ی ذخیره سازی داده‌ها در mysql

بررسی اصطلاح‌های موجود در دیتابیس‌های NoSQL

Collections

Collections در دیتابیس‌های NoSQL معادلی برای Tables در دیتابیس‌های SQL است و ما می‌توانیم داده‌های json خود را در آن ذخیره کنیم.

Documents

Documents معادلی برای Records یا Rows در دیتابیس‌های SQL است با این تفاوت که یک SQL Row می‌تواند به داده‌ی دیگری در Tables ارجاع داده شود.

Fields

Fields یا attributes معادلی برای Columns در Table دیتابیس‌های SQL است.

Schema

اگرفراموش نکرده باشید در بخش قبل گفتیم که دیتابیس‌های NoSQL مانند MongoDB از Schema خاصی پیروی نمی‌کنند. بااین‌حال ما می‌توانیم از Mongoose Schema در برنامه‌ی خود استفاده کرده و ساختار Documentها را در آن مشخص کنیم.

Models

Models با دریافت Schema یک instance از Document را معادل با دیتابیس‌های رابطه‌ای برای ما ایجاد می‌کند.

Mongoose در عمل

ممکن است با توضیح‌های بالا در رابطه با Models و Schema سوال‌هایی در ذهن شما به‌وجود آمده باشد که سعی می‌کنیم در ادامه‌ی مقاله با توضیح‌های بیشتر به آن‌ها پاسخ دهیم.

مقایسه‌ی Schema و Model در Mongoose

Mongoose Model را می‌توان یک Wrapper برای Mongoose Schema دانست. در Mongoose Schema می‌توانیم ساختار Document، مقادیر پیش‌فرض، اعتبارسنجی‌های مورد نیاز و … را تعریف کنیم درحالی‌که Mongoose Model یک interface از دیتابیس در اختیار ما قرار می‌دهد که به‌کمک آن می‌توانیم عملیات CRUD را بر روی دیتابیس اجرا کنیم.

در ادامه‌ی این بخش بعضی از کدهای مربوطه را قرار می‌دهیم اما سریعا وارد عمل نشوید و فقط توضیح‌ها را دنبال کنید.

قبل از ایجاد یک Model باید سه فرایند کلی طی شود:

  1. فراخوانی Mongoose
  2. تعریف Schema
  3. Export کردن Model

فراخوانی Mongoose

موردی که باید به آن توجه داشته باشید این است که تعریف Schema و Model نیازی به اتصال دیتابیس ندارد و در ادامه‌ی مقاله به این موضوع خواهیم پرداخت بنابراین برای فراخوانی Mongoose از کدهای زیر استفاده خواهیم کرد:

const mongoose = require('mongoose')
const Schema = mongoose.Schema;

تعریف Schema

در این بخش سعی داریم یک Schema با نام todoSchema ایجاد کنیم. برای ایجاد این Schema باید یک Object را به‌عنوان پارامتر بهnew Schema() پاس دهیم. درون این Object از یک key با نام description استفاده کرده‌ایم و به‌عنوان مقدار آن از یک Object دیگر استفاده کرده‌ایم که type و required بودن آن را مشخص کرده است:

const todoSchema = new Schema(
  {
    description: {
      type: String,
      required: true,
    },
    completed: {
      type: Boolean,
      default: false,
    },
  },
  {
    timestamps: true,
  }
);

به‌همین ترتیب فیلد دیگری با نام completed وجود دارد که type آن را Boolean قرار داده‌ایم و به‌طور پیش‌فرض مقدار آن false است.

اگر با دقت به کد فوق نگاه کنید متوجه خواهید شد که در پارامتر دوم یک key با نام timestamps با مقدار true وجود دارد. این پارامتر documentهایی با نام createdAt و updatedAt را به دیتابیس ما اضافه می‌کند.

علاوه‌براین‌ها در رابطه با typeهای مجاز نیز می‌توانید از لیست زیر استفاده کنید:

  • Array
  • Boolean
  • Buffer
  • Date
  • Mixed
  • Number
  • ObjectId
  • String

Export کردن Model

با استفاده از Schema‌ای که در مرحله‌ی قبل تعریف کردیم می‌توانیم Model خود را ایجاد کرده و آن را Export کنیم. برای این کار از model constructor در instance ایجاد شده از Mongoose کمک می‌گیریم و todoSchema را به آن پاس می‌دهیم:

var Todos = mongoose.model("Todo", todoSchema);

و پس از ایجاد Model باید در انتهای فایل آن را به‌شکل زیر Export کنیم:

module.exports = Todos;

توسعه‌ی برنامه

│   .env
│   .gitignore
│   .liaraignore
│   app.js
│   liara.json
│   package-lock.json
│   package.json
│
└───models
        todos.js

برای توسعه‌ی برنامه، یک پوشه با نام node-mongoose در مسیر دلخواه خود ایجاد کنید و بر اساس ساختار فوق باید مجددا درون آن یک پوشه‌ی جدید با نام models ایجاد کرده و فایل todos.js را در آن ایجاد کنید. درنهایت کدهای زیر را در فایل todos.js قرار دهید:

// models/todos.js

const mongoose = require("mongoose");
const Schema = mongoose.Schema;

const todoSchema = new Schema(
  {
    description: {
      type: String,
      required: [true, "please enter task details"],
    },
    completed: {
      type: Boolean,
      default: false,
    },
  },
  {
    timestamps: true,
  }
);

var Todos = mongoose.model("Todo", todoSchema);

module.exports = Todos;

ساختار پوشه‌‌های ما تا به اینجای کار به شکل زیر است:

node-mongoose
  - models
     - todos.js

حال با استفاده از Terminal سیستم‌عامل خود وارد پوشه‌ی node-mongoose شوید و مراحل زیر را به‌ترتیب انجام دهید:

  • یک فایل با نام app.js در ریشه‌ی پروژه ایجاد کنید.
  • دستور npm init -y را اجرا کنید.
  • برای نصب express، mongoose و dotenv دستورهای npm install express، npm install mongoose و npm install dotenv را اجرا کنید.
  • فایل .env را در مسیر اصلی پروژه ایجاد کنید تا در ادامه مقادیر DATABASE_URL و PORT را در آن مشخص کنیم.
  • همچنین فراموش نکنید که فایل .gitignore را در مسیر اصلی پروژه ایجاد کرده و فایل .env و پوشه‌ی node_modules را در آن قرار دهید تا از Push شدن داده‌های دسترسی به دیتابیس در GitHub یا GitLab جلوگیری شود اما برای اینکه ما به فایل .env برای استقرار برنامه در لیارا احتیاج داریم باید یک فایل دیگر با نام .liaraignore در مسیر اصلی پروژه ایجاد کرده و فقط پوشه‌ی node_modules را در آن قرار دهیم.

بیایید نگاهی به محتوای هر فایل داشته باشیم:

فایل .env

mongodb://<user>:<password>@<host>:<port>/<my-app>?authSource=admin
PORT=3000

فایل .gitignore

node_modules
.env

فایل .liaraignore

node_modules

فایل package.json

{
  "name": "node-mongoose",
  "version": "1.0.0",
  "description": "",
  "main": "app.js",
  "scripts": {
    "start": "node app.js"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "dotenv": "^8.2.0",
    "express": "^4.17.1",
    "mongoose": "^5.12.3"
  }
}

فایل app.js

const express = require("express");
const mongoose = require("mongoose");
const dotenv = require("dotenv");

dotenv.config({ path: ".env" });
const PORT = process.env.PORT;
const dbURI = process.env.DATABASE_URL;

//model
const Tasks = require("./models/todos");

const connect = mongoose.connect(dbURI, {
    useNewUrlParser: true,
    useUnifiedTopology: true,
});

connect.then(
    (db) => {
        console.log("Connected Successfully to Mongodb Server");

    },
    (err) => {
        console.log(err);
    }
);

const app = express();

app.use(express.json());

app.listen(PORT, () => {
    console.log(`Server is running at Liara Nodejs Service`);
});

پیاده‌سازی عملیات CRUD با استفاده از Mongoose

Mongoose دارای یک API انعطاف‌پذیر است و روش‌های پیشنهادی زیادی برای انجام هر کاری ارائه می‌دهد. بااین‌حال برای ساده نگه داشتن مقاله به یک روش بسنده می‌کنیم اما این موضوع را به یاد داشته باشید که می‌توانید بیشتر کارهای مورد نظر خود را به بیش از یک روش انجام دهید.

ایجاد یک document جدید در دیتابیس برنامه

در اینجا باید یک Object با نام newTask ایجاد کنیم که پارامتر description در آن تعریف شده باشد زیرا یک فیلد اجباری است. پس از آن با استفاده از Mongoose model که متد create() را دراختیار ما قرار می‌دهد می‌توانیم داده‌های خود را به دیتابیس اضافه کرده و به‌دلیل promise بودن این متد می‌توانیم در صورت رخ دادن خطا، آن را دریافت کرده و نمایش دهیم:

let newTask = {
      description: "task added using create",
};

Tasks.create(newTask)
  .then((data) => {
      console.log(data);
   })
   .catch((err) => {
      console.log(err);
});

نمایش تمام documentهای موجود در دیتابیس

برای دریافت تمام documentهایی که در collection ما ذخیره شده‌اند می‌توانیم به‌شکل زیر عمل کنیم:

//all tasks

Tasks.find({})
   .then((data) => {
       console.log("All tasks", data);
    })
    .catch((err) => {
       console.log(err);
 });

نمایش یک document خاص از دیتابیس

برای گذاشتن شرط و نمایش یک document خاص می‌توانیم به‌شکل زیر عمل کنیم:

Tasks.find({ completed: false })
    .then((data) => {
        console.log("All tasks", data);
    })
    .catch((err) => {
        console.log(err);
    });

به‌روزرسانی یک document خاص از دیتابیس

در این بخش می‌خواهیم مقدار completed یک document با شناسه 606a05138d4e7f3f58bdd444 را از false به true تغییر دهیم:

Tasks.findByIdAndUpdate({ _id: "606a05138d4e7f3f58bdd444" }, {
    $set: { completed: true },
},
    { new: true, useFindAndModify: false } //get updated result
)
    .then((data) => {
        console.log("Updated todo data", data);
    })
    .catch((err) => {
        console.log(err);
    });

حذف یک یا تمام documentهای موجود در دیتابیس

برای حذف تمام documentهای موجود در دیتابیس می‌توانیم به‌صورت زیر عمل کنیم:

Tasks.remove({});

یا می‌توانیم فقط شناسه‌ی خاصی را به‌صورت زیر حذف کنیم:

Tasks.findByIdAndRemove('606a092b4036e4614c5ca3bb')
    .then((data) => {
        console.log("All tasks", data);
    })
    .catch((err) => {
        console.log(err);
    });

استقرار پروژه بر روی لیارا

ایجاد یک برنامه جدید

برای ایجاد یک برنامه‌ی جدید باید وارد حساب کاربریتان در لیارا شوید و در تب برنامه‌ها بر روی دکمه‌ی ایجاد برنامه کلیک کنید.

ایجاد یک برنامه‌ی جدید در لیارا

بلافاصله بعد از کلیک بر روی دکمه‌ی ایجاد برنامه یک صفحه‌ی جدید برای شما باز می‌شود که بایستی در آن پلتفرم مورد نظرتان را انتخاب کرده و یک شناسه‌ی یکتا برای برنامه‌ی جدید خود درنظر بگیرید.

انتخاب پلتفرم nodejs و ثبت شناسه برنامه

پس از مشخص کردن شناسه از شما خواسته می‌شود که پلن مورد نظرتان را به‌نسبت نیازهای زیرساخت برنامه انتخاب کنید و درنهایت پس از انتخاب پلن مورد نظر بر روی دکمه‌ی ایجاد برنامه کلیک کنید.

انتخاب پلن و ایجاد یک برنامه‌ی جدید

نصب Liara CLI

پس از ایجاد برنامه‌ی جدید به صفحه‌ی راهنما ریدایرکت می‌شوید که دستورالعمل‌های استقرار برنامه به‌صورت متنی به‌همراه آموزش ویدیویی در آن قرار داده شده است.

صفحه‌ی راهنمای پلتفرم nodejs در لیارا

همان‌طور که مشاهده می‌کنید برای شروع باید Liara CLI را نصب کنیم که این کار به‌کمک یک پکیج منیجر با نام npm انجام می‌شود بنابراین توصیه می‌شود که حتما آموزش نصب Nodejs روی ویندوز را مطالعه کنید زیرا نصب Nodejs از پیش‌نیازهای استفاده‌ی این پکیج منیجر است. پس از نصب Nodejs که به‌همراه آن npm هم نصب می‌شود می‌توانید با اجرای دستور npm -v از نصب موفقیت آمیز این پکیج منیجر اطمینان حاصل کرده و با خیال راحت دستور زیر را برای نصب Liara CLI اجرا کنید:

npm install -g @liara/cli

ورود به حساب کاربری با Liara CLI

پس از نصب Liara CLI به‌راحتی با اجرای دستور liara login و وارد کردن اطلاعات می‌توانید وارد حساب کاربریتان شوید اما نکته‌ای که باید به آن دقت داشته باشید، انتخاب موقعیت جغرافیایی صحیح است.

انتخاب بین موقعیت‌های ایران و آلمان برای ورود به حساب کاربری لیارا

درنهایت اگر پس از وارد کردن اطلاعات حساب کاربری، ورود شما با موفقیت انجام شود پیام You have logged in successfully. را در Terminal دریافت خواهید کرد.

ورود موفقیت‌آمیز به لیارا

ایجاد یک دیتابیس جدید

برای ایجاد یک دیتابیس جدید باید از پنل کاربری لیارا در تب دیتابیس‌ها بر روی دکمه‌ی راه‌اندازی دیتابیس کلیک کنید.

راه‌اندازی یک دیتابیس جدید در لیارا

در صفحه‌ای که بلافاصله پس از کلیک بر روی راه‌اندازی دیتابیس برای شما باز می‌شود باید نوع و نسخه‌ی دیتابیس را انتخاب کرده و یک شناسه‌ی یکتا برای دیتابیس خود درنظر بگیرید.

انتخاب دیتابیس mongodb و ثبت شناسه دیتابیس

همچنین می‌توانید در بخش شبکه، گزینه‌ی دسترسی از طریق شبکه‌ی عمومی را برای امنیت بیشتر خاموش کنید اما توجه داشته باشید که با قطع دسترسی عمومی فقط برنامه‌های لیارا می‌توانند با این دیتابیس ارتباط برقرار کنند.

قطع کردن دسترسی از طریق شبکه‌ی عمومی

درنهایت باید پلن مورد نظرتان را انتخاب کرده و بر روی گزینه‌ی راه‌اندازی و نصب دیتابیس کلیک کنید تا دیتابیس شما ایجاد شود.

انتخاب پلن و راه‌اندازی دیتابیس

پس از راه‌اندازی دیتابیس روی سرویس ایجاد شده کلیک کرده و از سایدبار سمت راست بر روی نحوه‌ی اتصال کلیک کنید.

نحوه‌ی اتصال به دیتابیس در لیارا

داده‌های مورد نیاز برنامه‌ی شما برای اتصال به دیتابیس MongoDB در این صفحه قرار دارد که باید این داده‌ها را در فایل .env وارد کنید:

DATABASE_URL=mongodb://root:<censored-password>@mongodb:27017/my-app?authSource=admin
PORT=3000

استقرار پروژه

برنامه‌ی ما پس از وارد کردن داده‌های مورد نیاز برای اتصال به دیتابیس در فایل .env آماده‌ی استقرار در لیارا است و با اجرای دستور liara deploy می‌توانیم پروژه‌ی فعلی را در لیارا مستقر کنیم اما برای ساماندهی عملیات استقرار و جلوگیری از خطاها می‌توانیم یک فایل با نام liara.json در مسیر اصلی پروژه ایجاد کرده و داده‌های مورد نیاز برای استقرار برنامه را به شکل زیر در آن وارد کنیم:

{
  "platform": "node",
  "app": "node-app",
  "port": 3000
}

با این روش دیگر نیازی به انتخاب نام و وارد کردن پورت برنامه نیست و با اجرای دستور liara deploy تمام فرایند استقرار برنامه به‌صورت خودکار انجام می‌شود.

منبع: https://blog.teachmebro.com/building-a-crud-application-using-node-js-and-mongodb-atlas

خدمات رایگان لیارا

۲.۵ گیگابایت فضای ذخیره‌سازی ابری رایگان

۲.۵ گیگابایت Object Storage سازگار با پروتکل S3 با دیسک‌های SSD به‌صورت رایگان دریافت کنید.

هاست رایگان برای دیتابیس‌

دیتابیس‌های MariaDB، PostgreSQL و Redis را فقط با یک کلیک و به‌صورت رایگان تهیه کنید.

سرویس DNS رایگان

به سادگی دامنه‌تان را اضافه کنید و به صورت رایگان رکورد‌های آن را مدیریت کنید.

۱۰۰ هزار تومان اعتبار اولیه

بعد از ثبت نام در لیارا مبلغ ۱۰۰ هزار تومان اعتبار هدیه دریافت می‌کنید که با توجه به ساعتی بودن هزینه سرویس‌ها، می‌توانید تمامی خدمات پولی را برای چندین هفته رایگان استفاده کنید.

ارسال ۱۰۰ ایمیل تراکنشی رایگان در هر ماه

در سرویس ایمیل لیارا شما می‌توانید تا ۱۰۰ ایمیل رایگان در هر ماه ارسال کنید و فقط برای بیش از آن هزینه پرداخت کنید. (به‌همراه دسترسی SMTP)

هاست رایگان برای انواع وبسایت

تفاوتی ندارد برای وبسایت خود از Node استفاده می‌کنید یا Laravel و Django، در لیارا می‌توانید به صورت کاملا رایگان آن را میزبانی کنید.

توسعه‌دهندگان درباره‌ی ما چه می‌گویند

تجربه کار باliara_cloud@امروز خیلی خوب بود. یکی از سرویس هام رو منتقل کردم روش و راضیم. انقد سریع و جذاب کارم راه افتادم اصن باورم نمیشد! برعکس سرویس های PaaS دیگه با اون همه پیچیدگیشون. دمتون گرم
...

MohammadReza
liara testimonial
keikaavousi

بعد از بسته شدن @fandoghpaas و ناراحتی همه‌مون از اینکه یه سرویس خوب و صادق نمی‌تونه از پس هزینه‌ها بر بیاد، سرویسم رو منتقل کردم به پاس لیارا (https://liara.ir @liara_cloud) . تجربه راحت و خوب. تفاوت‌هایی داشت که کمی کار می‌خواست ولی تا الان کاملا راضی.

jadi
liara testimonial
jadi

یه خسته نباشید باید به تصمیمliara_cloud@بگم،
بعد از چندین روز سرکله زدن با سرویس های مشابه بالاخره تصمیم گرفتم لیارا رو امتحان کنم و باور نمیشه ۱۰ دقیقه بیشتر وقت نبرد،
دمتون گرم.

Arch
liara testimonial
EbadiDev

واسه سرویس PaaS با اختلاف لیارا بهترین رابط کاربری داره و یکی از مزیت‌های سرویس دیتابیس‌شون اینه که خودشون به صورت دوره‌ای بکآپ میگیرن.
...

Ali Najafi
liara testimonial
me_ali_najafi

یکی از کارهای خوبی که جدیداً میکنم اینه که یه دیتابیس روی لیارا میسازم و به پروژه وصل میکنم اینطوری هم خونه و هم محل کار دیتابیس بروز رو دارم و راحت میتونم ادامه بدم کار روliara_cloud@

Navid
liara testimonial
1navid

عاشقliara_cloud@شدم درسته در حد AWS نیست ولی خب تجربه خوبی واسه پروژه های داخل ایران ارائه میده، میتونم رو CD هم اجراش کنم

Amir H Shekari
liara testimonial
vanenshi

همراه شما هستیم

در خصوص سفارش یا استفاده از سرویس‌ها سوالی دارید؟
تلفن واحد فروش:
۰۲۵-۳۳۵۵۷۶۱۹ (روزهای کاری ۹ الی ۱۷)
تلفن واحد فروش: ۳۳۵۵۷۶۱۹-۰۲۵ (روزهای کاری ۹ الی ۱۷)