انتخاب کتابخانه‌ها و فریم‌وورک‌ها برای ای‌پی‌آی‌های REST در Node.js

گردآوری و تالیف : عرفان کاکایی
تاریخ انتشار : 12 مرداد 1397
دسته بندی ها : نود جی اس

آموزش‌های زیادی برای ساخت ای‌پی‌آی‌های REST بر روی Node.js وجود دارند، اما اغلب این آموزش‌ها از قبل کتابخانه‌ها یا فریم‌وورک را انتخاب کرده‌اند. این راهنما در جهت مقایسه کتابخانه‌های مختلف نوشته شده است.

معرفی

اگر با استفاده از ای‌پی‌آی‌های REST یک درخواست از طریق HTTP ارسال کنید و از طریق JSON با آن ارتباط برقرار کنید، ساخت یک API در Node.js می‌تواند به طرز شگفت‌انگیزی ساده باشد.

var express = require('express');
var app = express();

app.get('/greeting', function (req, res) {
  res.json({ hello: 'world' });
});

در ابتدا باید هم اصول طراحی و هم فناوری موجود در هر لایه را درک کنیم، و سپس می‌توانیم به انتخاب ابزارها و کتابخانه‌ها برگردیم.

بررسی اجمالی اصول طراحی REST

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

معنایی بودن:

  • End pointهای URI باید «منبع»، و خوانا باشند. مانند /items یا /users. یک تابع یا عملیات، یک منبع حساب نمی‌شوند.
  • افعال HTTP (GET، POST، PUT، DELETE) نمایانگر عملی که یک کاربر می‌تواند بر روی یک منبع انجام دهد، هستند.
  • کدهای پاسخ HTTP (مانند 201 = created، 404 = not found، 401 = nor authorized) نمایانگر آنچه که اتفاق می‌افتد هستند.
  • روابط (Relationshipها) می‌تواند به عنوان زیر منبع نشان داده شوند. و دوباره، این کار باعث خواناتر شدن می‌شود. مثلا /authors/{id}/posts نمایانگر پست‌های یک نویسنده خاص است.

بدون state بودن

  • سرور نیازی ندارد که از طرف کاربر، state را نگه دارد. نگهداری نشانگرهای موقت یا ذخیره‌سازی فایل‌های موقت بین درخواست‌ها، بدون state حساب نمی‌شود.

مدیریت صحیح فراخوانی‌های تکراری:

  • قابل cache بودن: متدهای GET و HEAD معمولا cache می‌شوند. API شما باید این را در نظر داشته باشد.
  • امنیت: GET، HEAD، OPTIONS و TRACE باید در حالت Readonly باشند و state را نیز تغییر ندهند.

لایه‌های اصلی برای راه‌اندازی یک ای‌پی‌آی REST

  • سرور و روتر HTTP
  • داده‌ها
  • امنیت
  • پروکسی

سرور و روتر HTTP

Node.js به طور پیشفرض یک سرور HTTP به همراه خود دارد.

این سرور پیشفرض، routing که برای تعریف endpointهای خود استفاده می‌کنیم را مدیریت نمی‌کند. ما می‌خواهیم GET /users را به یک تابع route کنیم، و GET /items را هم به یک تابع دیگر route کنیم. Routeها با چندین ترکیب افعال HTTP، pathها و پارامترها می‌توانند پیچیده شوند، ما خوشبختانه چندین فریم‌وورک داریم که می‌توانند routing را مدیریت کنند.

  • تا به حال، Express معروف‌ترین فریم‌وورک برای ساخت ای‌پی‌آی‌های REST بوده است. Express همچنین اولین فریم‌وورک منتشر شده توسط Moesif، و معروف‌ترین ابزار ادغام است. Express به ترکیب‌بندی‌ها و این که کدنویسی مهم‌تر از پیکربندی است، اعتقاد دارد. Routeهای شما دقیقا کنار جایی که منطق کار شما قرار دارد، کدنویسی می‌شوند. هیچ فایل مرکزی‌ای مانند routes.conf یا فایل مشابهی وجود ندارد. از این رو، اگر در حال ساخت یک ای‌پی‌آی REST هستید، هیچ چیز اضافه‌ای مانند الگوهای HTML و parserهای کوکی نخواهید داشت. در زیر، می‌توانید یک نمونه route در Express را ببینید.
  • با این که Koa از routing پشتیبانی نمی‌کند، در این لیست قرار داده شده است. گرچه، در برخی موارد یک جایگزین مناسب برای Express است. قبل از ES2016، Koa با co شروع شد تا فراخوانی‌های async را با async و await مدیریت کند.
  • Hapi توسط شرکت WalmartLabs ساخته شده است. این فریم‌وورک معتقد است که پیکربندی مهم‌تر از کدنویسی است. این مورد مفهومات بیشتری از ماژول‌های HTTP در Node را فراهم می‌کند.

کد مربوطه به این صورت است:

server.route({
    method: 'GET',
    path: '/{name}',
    handler: function (request, reply) {
          // ... where name is parameterized
    }
});
  • Restify خصوصا برای ای‌پی‌آی‌های REST طراحی شده است، و به همین دلیل برخی ویژگی‌های Express مانند الگوسازی و viewهای HTML را حذف کرده است، اما در عوض برخی موارد مورد نیاز APIها مانند محدودیت نرخ و پشتیبانی SPDY را اضافه کرده است. سینتکس Restify بسیار شبیه به Express است.

Serialize کردن JSON

JavaScript به طور پیشفرض از JSON.parse(my_json_string) و JSON.stringify(my_javascript_object) پشتیبانی می‌کند. گرچه، اگر این مسئله به صورت خودکار انجام می‌شد، همه چیز آسان‌تر میشد.

اگر از Express‌ استفاده می‌کنید، می‌توانید body-parser را به کار بگیرید. این دستور از انواع مختلفی از متن و داده‌های باینری و البته JSON پشتیبانی می‌کند.

دیتابیس‌ها

پس از این که یک دیتابیس را انتخاب می‌کنید، کتابخانه مورد انتخاب شما به سمت چیزی که با آن دیتابیس سازگار است، رانده می‌شود. اکوسیستم Node.js شامل درایور‌هایی برای انواع مختلف دیتابیس، از mongojs گرفته تا mysql و PostgreSQL است.

در حالیکه برای هر نوع دیتابیس در Node.js درایوری وجود دارد، شاید بخواهید بدون در نظر گرفتن فناوری SQL یا...،  استفاده از ORM را در نظر بگیرید. ORMها برای مدت زیادی در دنیای JavaScript و C# استفاده می‌شوند، و Node.js هم از این قضیه عقب نیست. یک ORM شما را قادر می‌سازد تا دیتابیس خود را در کد خود، به شکل یک آبجکت مدل‌سازی کنید، و خود ORM دریافت و بروزرسانی داده‌ها از دیتابیس اصلی را به عهده می‌گیرد.

برخی از ORMهای رایج در اکوسیستم Node.js:

  • Mongoose: این مورد، عملا ORM برای MongoDB است. با توجه به معروفیت استک‌های MEAN، این مورد هم بسیار معروف است.
  • Sequelizejs: این مورد بر پایه promise است، و با PostgreSQL، MySQL، SQLite و MSSQL کار می‌کند.
  • ORM
  • Bookshelf: یک Query builder که بر پایه Knex.js ساخته شده است.
  • Waterline: Waterline از مفاهیم یک آداپتور برای ترجمه مجموعه‌ای از متدهای از پیش تعیین شده در یک Query استفاده می‌کند. همچنین محدوده عظیمی از دیتابیس‌ها را نیز پشتیبانی می‌کند.

منابع برای نشانه‌های JWT

نشانه‌های JWT‌ در واقع آبجکت‌های JSON کامل هستند که به صورت base64 انکود شده‌اند و سپس یا با یک کلید متقارن، یا یک جفت کلید عمومی / خصوصی نشانه‌گذاری شده‌اند. اگر تصمیم گرفتید که JWT را به عنوان نشانه احراز هویت خود انتخاب کنید، برخی کتابخانه‌ها وجود دارند که می‌توانند به شما کمک کنند.

Jsonwebtoken یک کتابخانه کاربردی برای نشانه‌گذاری JWTها است.

برای ساخت یک نشانه برای کاربر خود، از کد زیر استفاده کنید:

var jwt = require('jsonwebtoken');
jwt.sign({
  exp: Math.floor(Date.now() / 1000) + (60 * 60),
  data: 'foobar'
}, 'secret');

این نشانه می‌تواند از هر یک از مفاهیم JSON مانند user_id تشکیل شود.

jwt.sign({
  exp: Math.floor(Date.now() / 1000) + (60 * 60),
  admin: true
}, 'secret');

از آنجایی که این نشانه با رمز شما نشانه‌گذاری شده است، می‌توانید مطمئن باشید که توسط یک شخص مخرب، دستکاری نشده است.

گرچه می‌توانید از کتابخانه jsonwebtoken استفاده کنید، کتابخانه دیگری نیز وجود دارد که ادغام با سرور و روتر HTTP را آسان‌تر می‌کند.

Express.jwt یک کتابخانه اوپن سورس، ساخته شده توسط Auth0 است که می‌تواند با هر روتر یا سرور استانداردی کار کند.

استفاده از آن بسیار ساده است:

var jwtMiddleware = require('express-jwt');

app.get('/protected',
  jwtMiddleware({secret: 'your secret'}),
  function(req, res) {
    if (!req.user.admin) return res.sendStatus(401);
    res.sendStatus(200);
  });

می‌توانید middleware مورد نظر را با استفاده از کلید تایید خود راه‌اندازی کنید، که middleware را قادر می‌سازد تا بررسی کند که آیا این نشانه توسط رمز شما نشانه‌گذاری شده است، یا نه. فیلدهای مربوطه، در req.user ذخیره می‌شوند.

محدودیت نرخ (Rare Limiting)

محدودیت نرخ برای جلوگیری از حملات DDoS مهم است. یک راه مناسب، استفاده از APIهایی مانند Tyk یا Apigee برای مدیریت APIهای خود است.

پروکسی برعکس

بسیاری از APIهایی که می‌سازیم، پشت یک پروکسی برعکس قرار می‌گیرند. یک پروکسی برعکس می‌تواند routingهای سطح بالایی را در بسیاری سرویس‌ها مدیریت کند. یک پروکسی برعکس، همچنین می‌تواند امنیت، ورود و cachingها را مدیریت کند.

Nginx و HaProxy دو مورد از معروف‌ترین پروکسی‌های HTTP هستند، اما کارهای زیادی در مرحله پیکربندی نیاز دارند. اکوسیستم Node.js یک پروکسی ساده ولی خوب به نام node-http-proxy دارد که می‌تواند مستقیما در برنامه Node.js شما اجرا شود.

سوکت‌های وب (Web Sockets)

فریم‌وورک‌هایی وجود دارند که شما را قادر می‌سازند تا به جای HTTP، با استفاده از سوکت‌های وب، API خود را مدیریت کنید. این موارد می‌توانند برای برنامه‌های Realtime مانند برنامه‌های چت مناسب باشند. دو مورد از معروف‌ترین‌های آن‌ها، Sails و Featurejs هستند.

نتیجه‌گیری

اکوسیستم Node.js یکی از منعطف‌ترین اکوسیستم‌ها بوده، و در حال تبدیل شدن به بزرگ‌ترین فریم‌وورک برای ساخت API است.

منبع

مقالات پیشنهادی

احراز هویت گوگل در Node.js

در این مقاله می خواهیم درمورد استفاده از احرازهویت گوگل در اپلیکیشن Node.js صحبت کنیم. برای شروع کار شما به یک پروژه اولیه node بهمراه پکیج ها و مدل ه...

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

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

10 افزونه متن باز و رایگان انتخاب‌گر تاریخ

استفاده از منوها به عنوان یک انتخاب‌گر تاریخ -date picker- انتخابی مرسوم است و جدای از آن آسان پیاده سازی می شود. اما بعد از گذشت دهه ها از منوهای MM/...

اعتبارسنجی رشته ها در Node.js

اعتبارسنجی اطلاعات ورودی یک بخش مهم و ضروری برای هر نرم افزاریست. شما باید از طبیعت اطلاعات بخصوص اونهایی که از منابع خارجی می آیند, با خبر باشید.