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

آموزش ساخت RESTful API با Nodejs


۲۷ شهریور ۱۳۹۹
آموزش ساخت RESTful API با Nodejs

از زمان اختراع WWW، فناوری‌های مختلفی مانند RPC و SOAP در ایجاد و پیاده سازی سرویس‌های وب نقش داشته‌اند. اما این فناوری‌ها برای مدیریت ارتباطات مناسب نبودند، بنابراین REST توسعه یافت تا به کاهش پیچیدگی‌های موجود کمک کند و سبک معماری جدیدی را برای طراحی برنامه مبتنی بر شبکه فراهم آورد. از آنجا که Node.js انقلابی در بخش بک‌اند برای توسعه‌دهندگان فرانت‌اند بوده است، در این مقاله تصمیم گرفتیم که روند ساخت REST API را با Node.js به صورت مقدماتی آموزش دهیم.

موضوع‌هایی که در ادامه مقاله به آنها می‌پردازیم، عبارتند از:

  1. REST API چیست؟
  2. اصول REST
  3. ساخت REST API با Node.js

REST API چیست؟

REST یا RESTful مخفف عبارت REpresentational State Transfer است. همچنین REST را می‌توان یک سبک معماری دانست که رویکردی برای اهداف ارتباطی ارائه می‌دهد و اغلب در توسعه سرویس‌های مختلف وب مورد استفاده قرار می‌گیرد. به عبارت ساده‌تر REST یک API (Application Program Interface) است که انتقال داده‌ها را از طریق WWW با ایجاد درخواست‌های HTTP مانند GET، POST، PUT و DELETE فراهم می‌کند.

سبک معماری REST به استفاده کمتر از پهنای باند کمک می‌کند و درنهایت باعث می‌شود برنامه برای اینترنت مناسب‌تر باشد. این سبک معماری را اغلب به عنوان زبان اینترنت می‌شناسند.

بهتر است برای درک اصل مطلب کمی بیشتر با ساختار و چگونگی کارکرد REST API آشنا شویم. اساسا REST API یک transaction را به ماژول‌های کوچک‌تر تبدیل می‌کند. اکنون هر یک از این ماژول‌ها دارای آدرسی یکتا است که برای بخشی از transaction مورد استفاده قرار می‌گیرند. این روش، انعطاف‌پذیری بیشتری ایجاد می‌کند اما برای شروع ساخت آن از ابتدا نیز به تلاش مضاعف‌تری احتیاج است.

توابع اصلی مورد استفاده در تمام معماری‌های REST، به شرح زیر است:

  1. GET: دسترسی read-only به داده را فراهم می‌کند.
  2. PUT: داده جدیدی ایجاد می‌کند.
  3. DELETE: داده را حذف می‌کند.
  4. POST: داده‌ موجود را به‌روزرسانی یا داده جدیدی ایجاد می‌کند.

برای اینکه برنامه شما به ‌عنوان یک برنامه RESTful API در نظر گرفته شود می‌بایست به اصول خاصی مقید باشد که این موارد را در ادامه بررسی خواهیم کرد.

اصول REST

دکتر Fielding یکی از افرادی است که در طراحی REST API در سال ۲۰۰۰ نقش داشته و چند اصل اساسی را تعریف کرده که ما در ادامه به برخی از آنها خواهیم پرداخت:

  1. Stateless
  2. Client-Server
  3. Uniform Interface
  4. Cache
  5. Layered system
  6. Code on demand

Stateless: ارتباطات در این معماری ماهیتا می‌بایست stateless باشند، به‌گونه‌ای که هر درخواست از سمت کاربر به سرور باید شامل تمام اطلاعاتی باشد که برای فهم درخواست در سرور نیاز می‌شود ولی این اطلاعات در سرور ذخیره نمی‌شوند. این محدودیت باعث ایجاد قابلیت‌های مقیاس‌پذیری، مطمئن بودن و مشاهده بهتر می‌شود. اطلاعات می‌توانند بخشی از URI، headers، body یا پارامتر‌های query-string باشند. URI برای شناسایی داده‌های منحصربه‌فرد مورد استفاده قرار می‌گیرد و stateها در body درخواست قرار می‌گیرند. هنگامی که پردازش درخواست توسط سرور انجام شد، پاسخ مناسب از طریق headers، status یا بدنه پاسخ به کاربر ارسال می‌شود.

Client-Server: یک رابط است که کاربران را از سرورها جدا می‌کند. این تفکیک به بهبود استفاده از رابط‌های کاربری کراس‌پلتفرم و افزایش مقیاس‌پذیری اجزای سرور کمک می‌کند.

Uniform Interface: ویژگی اصلی که معماری REST را از سایر معماری‌های مبتنی بر شبکه متمایز می‌کند، تاکید آن بر یکنواختی اینترفیس بین کامپوننت‌ها است و این معماری، رعایت موارد زیر در اینترفیس‌ها را اجبار می‌کند:

  1. شناسایی منابع
  2. دستکاری منابع با استفاده از representations
  3. پیام‌های self-descriptive
  4. hypermedia به عنوان موتور state برنامه

Cache: امروزه بیشتر برنامه‌ها برای ارائه بهتر از قابلیت cache استفاده می‌کنند. این کار با برچسب زدن پاسخ از سرور به عنوان cacheable یا non-cacheable انجام می‌شود. اگر پاسخ cacheable تعریف شود، در این صورت حافظه پنهان کاربر می‌تواند از داده‌های این پاسخ برای پاسخ‌های معادل آینده استفاده کند. همچنین به شما در جلوگیری از استفاده مجدد داده‌های قدیمی کمک می‌کند.

Layered system: معماری لایه لایه سیستم با محدود کردن رفتارهای کامپوننت‌ها از ثبات بیشتری برخوردار است. این معماری تعادل بار را فراهم می‌کند و حافظه پنهان مشترک را برای ارتقا مقیاس‌پذیری فراهم می‌کند. معماری لایه‌ای همچنین به افزایش امنیت برنامه کمک می‌کند زیرا اجزای موجود در هر لایه نمی‌توانند فراتر از لایه‌ای که در آن قرار دارند، تعامل داشته باشند.

Code on demand: این مورد یک محدودیت اختیاری است و زیاد از آن استفاده نمی‌شود. اجازه می‌دهد تا کد کاربران یا برنامه‌های کوچک از طریق رابط کاربری در برنامه بارگیری و گسترش یابد. در واقع با ایجاد یک برنامه هوشمند که به ساختار کد خود متکی نیست، کار را برای کاربر ساده‌تر می‌کند.

اکنون که متوجه شدید REST API چیست و با آنچه که برای ساخت یک برنامه کارآمد باید به خاطر بسپارید، آشنا شدید، به مرحله بعد وارد می‌شویم.

ساخت REST API با Node.js

در اینجا با استفاده از Node.js و Express.js یک برنامه CRUD REST برای مدیریت کتابخانه ایجاد خواهیم کرد. برای ساخت برنامه می‌بایست موارد زیر را در پروژه و سیستم خود نصب داشته باشید:

  1. Node.js
  2. Express.js
  3. Joi
  4. nodemon (Node Monitor)

ابتدا باید مسیر پروژه خود را ایجاد کنید. بعد خط فرمان را بازکرده و به مسیر پروژه‌تان بروید. با استفاده از دستور زیر کار را آغاز می‌کنیم:

npm init

زمانی که شما کلید Enter را فشار دهید، Node.js از شما می‌خواهد جزئیاتی را برای ساخت فایل package.json وارد کنید.

راهنمای دستور npm init

در اینجا می‌توانید فایل اصلی پروژه خود را به همراه چند مورد دیگر وارد کنید. برای این مثال از script.js به عنوان فایل اصلی پروژه استفاده خواهیم کرد. سپس با استفاده از دستور زیر می‌توانید Express.js را نصب کنید:

npm i express

دستور زیر نیز joi را نصب می‌کند:

npm i joi

سرانجام پکیجی با نام nodemon را می‌توانید برای مانیتورینگ پروژه‌تان نصب کنید. با استفاده از nodemon دیگر مجبور نیستید که پس ایجاد تغییرها، سرور Node.js را مجدد راه‌اندازی کنید. این پکیج تغییرها را شناسایی کرده و سرور را برای شما مجددا راه‌اندازی می‌کند. با استفاده از دستور زیر به کمک npm می‌توانید پکیج nodemon را نصب کنید.

npm i -g nodemon

فایل package.json:

{
  "name": "restful-api",
  "version": "1.0.0",
  "description": "",
  "main": "script.js",
  "scripts": {
    "test": "nodemon script.js"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "express": "^4.17.1",
    "joi": "^17.2.1"
  }
}

فایل script.js:

const express = require('express');
const Joi = require('joi'); //used for validation
const app = express();
app.use(express.json());

const books = [
    { title: 'Harry Potter', id: 1 },
    { title: 'Twilight', id: 2 },
    { title: 'Lorien Legacies', id: 3 }
]

//READ Request Handlers
app.get('/', (req, res) => {
    res.send('Welcome to Edurekas REST API with Node.js Tutorial!!');
});

app.get('/api/books', (req, res) => {
    res.send(books);
});

app.get('/api/books/:id', (req, res) => {
    const book = books.find(c => c.id === parseInt(req.params.id));

    if (!book) res.status(404).send('<h2 style="font-family: Malgun Gothic; color: darkred;">Ooops... Cant find what you are looking for!</h2>');
    res.send(book);
});

//CREATE Request Handler
app.post('/api/books', (req, res) => {

    const { error } = req.body;
    if (error) {
        res.status(400).send(error.details[0].message)
        return;
    }
    const book = {
        id: books.length + 1,
        title: req.body.title
    };
    books.push(book);
    res.send(book);
});

//UPDATE Request Handler
app.put('/api/books/:id', (req, res) => {
    const book = books.find(c => c.id === parseInt(req.params.id));
    if (!book) res.status(404).send('<h2 style="font-family: Malgun Gothic; color: darkred;">Not Found!! </h2>');

    const { error } = req.body;
    if (error) {
        res.status(400).send(error.details[0].message);
        return;
    }

    book.title = req.body.title;
    res.send(book);
});

//DELETE Request Handler
app.delete('/api/books/:id', (req, res) => {

    const book = books.find(c => c.id === parseInt(req.params.id));
    if (!book) res.status(404).send('<h2 style="font-family: Malgun Gothic; color: darkred;"> Not Found!! </h2>');

    const index = books.indexOf(book);
    books.splice(index, 1);

    res.send(book);
});



//PORT ENVIRONMENT VARIABLE
const port = process.env.PORT || 8080;
app.listen(port, () => console.log(`Listening on port ${port}..`));

اکنون باید کدهایی که نوشته‌ایم را آزمایش کرده و از صحت کارکرد آن مطمئن شویم. برای اجرای سروری که توسط Express.js ساخته‌ایم، از دستور زیر استفاده خواهیم کرد.

npm test

برای ادامه کار از یک افزونه در مرورگر chrome به نام Postman استفاده می‌کنیم. وقتی که Postman را نصب کردید، می‌توانید آن را باز کرده و آزمایش برنامه‌تان را شروع کنید. برای شروع متد GET را آزمایش می‌کنیم. برای این کار باید متد GET را از لیست کشویی انتخاب کرده، URI را وارد کنید و دکمه Send را بزنید. اگر کدتان درست کار کند، لیست تمام کتاب‌هایی را که به صورت دستی در کد خود اضافه کرده‌ایم، مشاهده خواهید کرد. در تصویر زیر می‌توانید نتیجه را ببینید.

متد get در postman

اکنون بیایید سعی کنیم که کتاب جدیدی را به لیست موجود اضاف کنیم. برای این منظور متد POST را انتخاب و URI پروژه‌مان را وارد می‌کنیم، سپس بر روی Body کلیک و raw را انتخاب کرده و مانند تصویر زیر، نوع Body را بر روی JSON تنظیم می‌کنیم.

سپس می‌توانید در قسمت متن، عنوان کتاب خود را همانطور که نشان داده شده تایپ کنید و Send را فشار دهید.

متد post در postman

اگر متد POST شما صحیح باشد و کدها درست کار کنند، بدنه پاسخ شامل عنوان کتاب همراه با شناسه آن خواهد بود. اکنون سعی کنید عنوان کتاب را به روز کنید. درحال حاضر عنوان کتاب “Angels and Demons” است و می‌خواهیم آن را به “Angels & Demons” به روز کنیم. برای به‌روزرسانی داده‌ها، ابتدا می‌بایست متد PUT را از منوی کشویی Postman انتخاب کرده و URI شناسه کتابی که می‌خواهید عنوان آن را به روز کنید، وارد کنید. سپس در قسمت Body می‌توانید عنوان جدید کتاب را مشابه تصویر زیر وارد کرده و Enter را فشار دهید.

متد put در postman

در پاسخ به این درخواست، شناسه آیدی با عنوان جدید به شما نشان داده خواهد شد.

بیایید در پایان با متد DELETE درخواستی برای حذف رکورد موجود ارسال کنیم. برای این کار از منوی کشویی متد DELETE را انتخاب و URI را همراه با شناسه کتابی که می‌خواهید حذف شود تایپ کرده و درنهایت Enter را فشار دهید. اگر موفقیت آمیز بود، جزئیات کاملی از کتابی که حذف کرده‌اید را مشاهده خواهید کرد.

متد delete در postman

اکنون برای دریافت لیست نهایی کتاب‌هایمان، درخواستی را با متد GET به سرور ارسال می‌کنیم.

دریافت نتیجه نهایی با متد get

همان‌طور که در تصویر بالا می‌بینید، متن پاسخ شامل سه کتاب است که شناسه شماره ۳ در میان آنها وجود ندارد، زیرا قبلا توسط متد DELETE آن را حذف کرده‌ایم. برای مشاهده مقالات مرتبط به Node.js می‌توانید این آدرس را مشاهده کنید.

منبع: https://www.edureka.co/blog/rest-api-with-node-js