چگونه یک دروازه API سفارشی با Node.js بسازیم
در عصر میکروسرویسها ، که برنامهها به سرویسهای کوچکتر و مستقلاً قابل استقرار تقسیم میشوند، مدیریت و ایمنسازی ارتباط بین این سرویسها بسیار مهم میشود. اینجا جایی است که یک دروازه API وارد عمل می شود.
یک دروازه API به عنوان یک نقطه ورودی مرکزی برای تمام درخواست های مشتری عمل می کند. عملکردهای مختلفی مانند مسیریابی، تعادل بار، احراز هویت و محدود کردن نرخ را فراهم می کند.
در این مقاله، نحوه ایجاد یک دروازه API سفارشی با استفاده از Node.js را تحلیل خواهیم کرد.
در اینجا چیزی است که ما پوشش خواهیم داد:
پیش نیازها
این یک راهنمای مبتدی است که پیروی از آن باید نسبتاً آسان باشد. اما برای درک کامل و استفاده حداکثری از آن، دانش اولیه Node.js مانند نصب، راهاندازی و راهاندازی سرور حیاتی است.
بدون هیچ مقدمه ای، بیایید حفاری کنیم!
API Gateway چیست؟
دروازههای API به عنوان واسطهای بین مشتریان و سرویسهای بکاند در معماری میکروسرویس عمل میکنند. آنها پیچیدگی خدمات اساسی را انتزاع می کنند و یک API یکپارچه را در معرض دید مشتریان قرار می دهند.
با ادغام چندین نقطه پایانی سرویس در یک نقطه ورودی واحد، دروازههای API کد سمت مشتری را ساده کرده و مقیاسپذیری و عملکرد کلی سیستم را بهبود میبخشد.
در مقایسه با سایر راه حل های محبوب دروازه API مانند Kong، AWS API Gateway و Tyke، ساخت یک دروازه API سفارشی با استفاده از Node.js گزینه های انعطاف پذیری و سفارشی سازی متناسب با نیازهای پروژه خاص شما را ارائه می دهد.
برای درک کمی بیشتر از چیستی دروازه API، توصیه میکنم اگر این کار را نکردهاید ، این مقاله را تحلیل کنید .
مزایای استفاده از دروازه API:
بهبود مقیاسپذیری و عملکرد از طریق مسیریابی درخواست و متعادلسازی بار: دروازههای API مسیریابی درخواست و متعادلسازی بار را تسهیل میکنند و ترافیک ورودی را در چندین سرویس پشتیبان توزیع میکنند تا عملکرد و مقیاسپذیری بهینه را تضمین کنند.
کد سمت کلاینت ساده شده با ارائه نقطه پایانی API یکپارچه : با یک نقطه پایانی یکپارچه API ارائه شده توسط دروازه API، مشتریان می توانند به طور یکپارچه با چندین سرویس تعامل داشته باشند، پیچیدگی را کاهش می دهند و قابلیت نگهداری کد سمت سرویس گیرنده را بهبود می بخشند.
امنیت پیشرفته : دروازههای API آپشن های امنیتی قوی مانند احراز هویت، مجوز، و محدود کردن نرخ را ارائه میدهند، و از خدمات باطن در برابر دسترسی غیرمجاز و تهدیدات امنیتی بالقوه محافظت میکنند.
امنیت در دروازه های API
امنیت در توسعه نرمافزار مدرن از اهمیت بالایی برخوردار است، بهویژه زمانی که با سیستمهای توزیعشده و میکروسرویسها سروکار داریم. دروازه های API نقش مهمی در اجرای اقدامات امنیتی برای محافظت از داده های حساس و جلوگیری از دسترسی غیرمجاز به API ها ایفا می کنند.
ویژگی های امنیتی متداول پیاده سازی شده در دروازه های API عبارتند از:
احراز هویت JWT: تأیید هویت مشتریان با استفاده از JSON Web Tokens (JWT) برای اطمینان از ارتباط ایمن بین مشتریان و خدمات باطن.
یکپارچه سازی OAuth2: ارائه مکانیزم های کنترل دسترسی و مجوز با استفاده از پروتکل های OAuth2 برای احراز هویت و تأیید درخواست های مشتری.
خاتمه SSL: رمزگذاری ترافیک بین کلاینت ها و دروازه API با استفاده از پروتکل های SSL/TLS برای محافظت از داده های در حال انتقال در برابر استراق سمع و دستکاری.
اکنون باید یک نمای کلی از چیستی دروازه API و چرایی اهمیت آن داشته باشید.
در بخش بعدی، به فرآیند ساخت یک دروازه API سفارشی با استفاده از Node.js خواهیم پرداخت. من نحوه پیاده سازی ویژگی های امنیتی را با استفاده از بسته http-proxy-middleware نشان خواهم داد.
چگونه یک دروازه API سفارشی با Node.js بسازیم
همانطور که قبلاً صحبت کردم، ما از Node.js برای این آموزش استفاده خواهیم کرد. به نظر من Node.js ساده ترین و محبوب ترین چارچوب وب است. هر کسی می تواند نحوه استفاده از آن را بیاموزد.
برای این راهنما، فرض میکنم که شما قبلاً از Node.js و نحوه راهاندازی سرور میدانید یا درک اولیهای دارید.
شروع به کار - نصب و راه اندازی
برای شروع، یک پوشه جدید به نام "API-gateway" کاملاً خارج از قسمت جلویی یا کد بکاند خود ایجاد کنید. پس از ایجاد پوشه، آن را در ترمینال خود باز کنید و npm init -y
اجرا کنید. این npm
تنظیم میکند و سپس شما آماده هستید تا چیزها را منتشر کنید!
ما از چند بسته NPM استفاده خواهیم کرد و بهتر است اکنون آنها را نصب کنیم. مهمترین آنها http-proxy-middleware
است. این میان افزار یا بسته چیزی است که درخواست های ما را از یک نقطه پایانی (www.domain.com/auth ) به هر نقطه پایانی مربوطه (www.externaldomain.com/v1/bla/auth، www.externaldomain.com/v1/bla/projects) هدایت می کند. ) همانطور که در میکروسرویس های ما تعریف شده است.
برای نصب http-proxy-middleware، کافی است npm i http-proxy-middleware
در پوشه ریشه ترمینال خود اجرا کنید. اگر نصب شده باشد، می توانید بروید.
در مرحله بعد، ما به بسته های باقی مانده نیاز داریم. به سادگی npm install express cors helmet morgan
.
دستور بالا موارد زیر را نصب می کند:
Express : کتابخانه Node.js ما برای ایجاد سرور و اجرای کد ما
Cors : میانافزار برای مدیریت و کنترل درخواستهای متقابل
Helmet : یک میان افزار دیگر برای ایمن سازی هدرهای پاسخ HTTP ما
مورگان : یک ابزار گزارش گیری که می توانیم از آن برای ردیابی گزارش های موفقیت و خطا استفاده کنیم
در آخر Nodemon را نصب کنید. این ابزاری است که هر زمان که فایلی را با استفاده از npm install --save-dev nodemon
ذخیره میکنید، سرور شما را بالا میبرد.
حالا به فایل package.js خود بروید و بخش اسکریپت ها را به روز کنید. می بایست شبیه به این باشه:
"scripts": { "start": "node index.js", "dev": "nodemon index.js", "test": "echo \"Error: no test specified\" && exit 1" },
برای اینکه در نهایت شروع به آزمایش چیزها کنید، یک فایل جدید به نام index.js در همان پوشه api-gateway ایجاد کنید.
اگر همه چیز را درست انجام دهید، باید فایل های زیر را داشته باشید:
همه اش را بگذار کنار هم
یک تمرین کد خوب این است که چیزها را تا حد امکان به اجزای کوچکتر تقسیم کنید.
اما برای این راهنما، میخواهیم این قانون را بشکنیم و تمام کدها را در یک فایل index.js
که از مراحل بالا ایجاد کردیم، قرار دهیم. ما این کار را به این صورت انجام خواهیم داد زیرا داشتن فایل های بسیار زیاد و تنظیم بیش از حد پیچیده در اینجا ممکن است گیج کننده باشد، به خصوص زمانی که شما در حال یادگیری نحوه کار کردن هستید.
ابتدا فایل index.js را که ایجاد کرده اید باز کنید و کد زیر را در آن قرار دهید:
const express = require("express"); const cors = require("cors"); const helmet = require("helmet"); const morgan = require("morgan"); const { createProxyMiddleware } = require("http-proxy-middleware");
در کد بالا ما فقط بسته ها را وارد می کنیم.
در مرحله بعد، بسته های وارد شده را به صورت زیر مقداردهی و راه اندازی کنید:
// Create an instance of Express app const app = express(); // Middleware setup app.use(cors()); // Enable CORS app.use(helmet()); // Add security headers app.use(morgan("combined")); // Log HTTP requests app.disable("x-powered-by"); // Hide Express server information
به یاد داشته باشید که یک دروازه API یک منبع واحد از حقیقت برای همه خدمات یا URL های خارجی شما است. این بدان معناست که شما باید سرویس ها یا URL های دیگری داشته باشید که می خواهید درخواست ها را به آنها فوروارد کنید.
با فرض اینکه شما قبلاً سرویس های دیگر خود را به صورت محلی یا مستقر دارید، به بخش بعدی کد حرکت می کنیم.
// Define routes and corresponding microservices const services = [ { route: "/auth", target: "https://your-deployed-service.herokuapp.com/auth", }, { route: "/users", target: "https://your-deployed-service.herokuapp.com/users/", }, { route: "/chats", target: "https://your-deployed-service.herokuapp.com/chats/", }, { route: "/payment", target: "https://your-deployed-service.herokuapp.com/payment/", }, // Add more services as needed either deployed or locally. ];
در کد بالا، ما یک فهرست آرایه خدمات ایجاد کردیم و اشیایی را تعریف کردیم که هر کدام شامل مسیرها (جایی که درخواست میکنیم) و اهداف (جایی که درخواستها به آنها ارسال میشوند) هستند.
مطمئن شوید که مسیرها و اهداف را متناسب با نیازهای خود به روز کنید.
آیا می توانید حدس بزنید که در ادامه چیست؟
خوب، بالاخره زمان ایجاد منطق ساده برای ارسال درخواستها به URL هدف ما، تنظیم محدودیت نرخ و زمانبندی فرا رسیده است. و آیا می دانید در آینده چه خواهد شد؟ یک نمونه کد، lol:
// Define rate limit constants const rateLimit = 20; // Max requests per minute const interval = 60 * 1000; // Time window in milliseconds (1 minute) // Object to store request counts for each IP address const requestCounts = {}; // Reset request count for each IP address every 'interval' milliseconds setInterval(() => { Object.keys(requestCounts).forEach((ip) => { requestCounts[ip] = 0; // Reset request count for each IP address }); }, interval); // Middleware function for rate limiting and timeout handling function rateLimitAndTimeout(req, res, next) { const ip = req.ip; // Get client IP address // Update request count for the current IP requestCounts[ip] = (requestCounts[ip] || 0) + 1; // Check if request count exceeds the rate limit if (requestCounts[ip] > rateLimit) { // Respond with a 429 Too Many Requests status code return res.status(429).json({ code: 429, status: "Error", message: "Rate limit exceeded.", data: null, }); } // Set timeout for each request (example: 10 seconds) req.setTimeout(15000, () => { // Handle timeout error res.status(504).json({ code: 504, status: "Error", message: "Gateway timeout.", data: null, }); req.abort(); // Abort the request }); next(); // Continue to the next middleware } // Apply the rate limit and timeout middleware to the proxy app.use(rateLimitAndTimeout); // Set up proxy middleware for each microservice services.forEach(({ route, target }) => { // Proxy options const proxyOptions = { target, changeOrigin: true, pathRewrite: { [`^${route}`]: "", }, }; // Apply rate limiting and timeout middleware before proxying app.use(route, rateLimitAndTimeout, createProxyMiddleware(proxyOptions)); });
من یکسری نظرات کد خوب را اضافه کردم تا به شما کمک کند بفهمید چه خبر است.
اگر می دانید در بالا چه اتفاقی می افتد به شما تبریک می گویم. اگر این کار را نمی کنید، می توانید در مورد بسته http-proxy-middleware مطالعه کنید.
اما بیایید جدی بگیریم، هنوز کارمان تمام نشده است.
کد بالا هنوز کار نمی کند، زیرا ما به یک چیز دیگر نیاز داریم: نوشتن یک تابع برای راه اندازی سرور در صورت فراخوانی.
پس از تمام کدهایی که در بالا اضافه کرده اید، نمونه کد زیر را به پایین index.js اضافه کنید:
// Define port for Express server const PORT = process.env.PORT || 5000; // Start Express server app.listen(PORT, () => { console.log(`Gateway is running on port ${PORT}`); });
با این کار، وقتی npm run dev
اجرا میکنید، سرور شما را میچرخاند و باید بتوانید با استفاده از ابزارهایی مانند Postman یا هر ابزار دیگری که برای آزمایش API استفاده میکنید، آن را آزمایش کنید.
حالا قبل از رفتن، بیایید سعی کنیم این را کمی تند کنیم!
بیایید یک تابع 404 برای ردیابی و بازگرداندن یک پیام زیبای 404 به کاربر اضافه کنیم، در صورتی که کاربر به آدرسی که وجود ندارد پیمایش کند یا درخواستی ارسال کند.
پس در آرایه خدمات ما که در بالا تعریف شده است، هیچ مسیری برای products
تعریف نشده است. این بدان معناست که اگر کاربر درخواستی را به /product
ارسال کند، با خطای سرور مواجه میشود، زیرا درخواست قابل رسیدگی نیست.
برای اینکه به کاربر بگوییم URL پیدا نشده است، میتوانیم نمونه کد زیر را درست قبل از تعریف پورت و گوش دادن به آن اضافه کنیم:
// Handler for route-not-found app.use((_req, res) => { res.status(404).json({ code: 404, status: "Error", message: "Route not found.", data: null, }); }); // Define port for Express server
نتیجه
ساخت یک دروازه API سفارشی با Node.js به توسعه دهندگان راه حلی انعطاف پذیر و قابل تنظیم برای مدیریت، مسیریابی و ایمن سازی تماس های API در معماری میکروسرویس ها ارائه می دهد.
در طول این آموزش، مفاهیم اساسی دروازههای API، از جمله نقش آنها در سادهسازی کد سمت مشتری، بهبود مقیاسپذیری و عملکرد، و افزایش امنیت را تحلیل کردهایم.
با استفاده از قدرت Node.js و بسته http-proxy-middleware
، نحوه پیادهسازی یک دروازه API اساسی را نشان دادهایم که درخواستهای پراکسی را به چندین سرویس پشتیبان ارائه میکند. ما همچنین دروازه خود را با آپشن های ضروری مانند محدود کردن نرخ و زمانبندی بهبود بخشیدهایم تا ارتباط مطمئن و ایمن بین مشتریان و خدمات را تضمین کنیم.
همانطور که به کاوش در دنیای میکروسرویس ها و سیستم های توزیع شده ادامه می دهید، به یاد داشته باشید که دروازه های API نقش مهمی در هماهنگ سازی ارتباطات و اجرای اقدامات امنیتی دارند. چه بخواهید یک راه حل سفارشی بسازید یا از پلتفرم های دروازه موجود استفاده کنید، درک اصول و بهترین شیوه های ذکر شده در این آموزش به شما قدرت می دهد تا سیستم های قوی و مقیاس پذیر را معمار کنید.
من شما را تشویق میکنم که نمونههای کد ارائه شده را آزمایش کنید و گزینههای سفارشیسازی بیشتر را برای مطابقت با نیازهای منحصر به فرد پروژه خود تحلیل کنید. کد منبع کامل این آموزش را می توانید در اینجا بیابید: https://github.com/irorochad/api-gateway .
از اینکه در این سفر به من پیوستید تا پیچیدگیهای دروازههای API را با Node.js کشف کنید، سپاسگزارم. کد نویسی مبارک!
ارسال نظر