پست

بررسی عمیق API Gateway برای مصاحبه‌های طراحی سیستم

توضیح عملی API Gateway شامل مسئولیت‌های اصلی، مسیر یک درخواست، مسیریابی، middleware، کش، مقیاس‌دهی، گزینه‌های مدیریت‌شده و متن‌باز و زمان مناسب پیشنهاد آن در مصاحبه

بررسی عمیق API Gateway برای مصاحبه‌های طراحی سیستم

API Gateway

در این فصل یاد می‌گیریم کی و چطور API Gateway را به‌طور مؤثر در مصاحبه‌های طراحی سیستم وارد کنیم.

API Gateway چیست؟

احتمالاً امروز با یک API Gateway تعامل داشته‌اید، حتی اگر متوجه نشده باشید. این‌ها جزء اصلی معماری‌های مدرن‌اند، به‌خصوص با ظهور میکروسرویس‌ها.

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

API Gateway مثل یک نقطه ورود واحد برای همه درخواست‌های کلاینت عمل می‌کند و آن‌ها را مدیریت و به سرویس‌های backend مناسب مسیریابی می‌کند. همان‌طور که میز پذیرش هتل check-in، تخصیص اتاق و درخواست‌های مهمان را رسیدگی می‌کند، API Gateway هم middlewareهای متمرکزی مثل احراز هویت، مسیریابی و رسیدگی به درخواست را مدیریت می‌کند.

تکامل API Gatewayها هم‌زمان با ظهور معماری میکروسرویس بوده است. وقتی اپلیکیشن‌های یکپارچه (monolithic) به سرویس‌های کوچک‌تر و تخصصی‌تر تقسیم شدند، نیاز به یک نقطه کنترل متمرکز روشن شد. بدون API Gateway کلاینت‌ها باید مستقیم درباره چند سرویس بدانند و با آن‌ها ارتباط بگیرند. مثل این است که مهمان‌های هتل مجبور باشند برای هر درخواست، اعضای کارکنان را خودشان پیدا کنند.

API Gatewayها اجزای نازک و نسبتاً سادهای هستند که هدف مشخصی دارند. در این بررسی عمیق روی چیزهایی تمرکز می‌کنیم که برای مصاحبه‌های طراحی سیستم لازم دارید، بدون این‌که مسئله را پیچیده‌تر کنیم.

مسئولیت‌های اصلی

کارکرد اصلی gateway مسیریابی درخواست (request routing) است، یعنی تعیین این‌که هر درخواست ورودی را کدام سرویس backend باید مدیریت کند. اما کار آن‌ها فقط این نیست.

جالب است که اغلب از کاندیداها می‌خواهم gateway را وارد طراحی مصاحبه کنند، و آن‌ها تأکید می‌کنند که این gateway همه این middlewareها را انجام می‌دهد، اما هرگز دلیل اصلی نیاز به آن را نمی‌گویند: مسیریابی درخواست.

امروزه API Gatewayها برای رسیدگی به دغدغه‌های مشترک بین چند سرویس (cross-cutting concerns) یا middleware مثل احراز هویت، Rate Limiting، کش، SSL termination و موارد دیگر استفاده می‌شوند.

مسیر یک درخواست

بیایید یک درخواست را از ابتدا تا انتها دنبال کنیم. درخواست‌های ورودی از کلاینت‌ها معمولاً از طریق HTTP به API Gateway می‌رسند، اما می‌توانند gRPC یا هر پروتکل دیگری هم باشند. از آنجا، gateway هر middlewareای را که پیکربندی کرده‌اید اعمال می‌کند و بعد درخواست را به سرویس backend مناسب هدایت می‌کند.

  1. اعتبارسنجی درخواست: درخواست اعتبارسنجی می‌شود.
  2. middleware: API Gateway میان‌افزارها (احراز هویت، Rate Limiting و مانند آن) را اعمال می‌کند.
  3. مسیریابی: API Gateway درخواست را به سرویس backend مناسب هدایت می‌کند.
  4. پردازش در backend: سرویس backend درخواست را پردازش می‌کند و پاسخ برمی‌گرداند.
  5. تبدیل پاسخ: API Gateway پاسخ را تبدیل می‌کند و به کلاینت برمی‌گرداند.
  6. کش (اختیاری): در صورت نیاز، پاسخ برای درخواست‌های آینده کش می‌شود.

نگاه دقیق‌تری به هر مرحله بیندازیم.

۱) اعتبارسنجی درخواست

قبل از هر کار دیگر، API Gateway بررسی می‌کند درخواست‌های ورودی درست قالب‌بندی شده‌اند و همه اطلاعات لازم را دارند. این اعتبارسنجی شامل بررسی معتبر بودن URL، وجود هدرهای الزامی و هم‌خوانی بدنه درخواست (در صورت وجود) با قالب موردانتظار است.

این اعتبارسنجی زودهنگام مهم است، چون کمک می‌کند مشکلات آشکار را قبل از رسیدن به سرویس‌های backend پیدا کنید. مثلاً اگر اپلیکیشن موبایل payload ناقص JSON بفرستد یا فراموش کند کلید API لازم را اضافه کند، فایده‌ای ندارد آن درخواست را بیشتر در سیستم جلو ببرید. gateway می‌تواند سریع آن را رد کند و پیام خطای مفید برگرداند. سرویس‌های backend را هم از هدر دادن زمان و منابع برای درخواست‌هایی که هرگز موفق نمی‌شدند نجات می‌دهد.

۲) Middleware

API Gatewayها را می‌توان برای انجام کارهای مختلف middleware پیکربندی کرد. مثلاً ممکن است بخواهید:

  • درخواست‌ها را با توکن‌های JWT احراز هویت کنید.
  • برای جلوگیری از سوءاستفاده، نرخ درخواست را محدود (Rate Limit) کنید.
  • اتصال‌های SSL را خاتمه دهید (SSL termination).
  • ترافیک را log و مانیتور کنید.
  • پاسخ‌ها را فشرده کنید.
  • هدرهای CORS را مدیریت کنید.
  • IPها را در whitelist یا blacklist قرار دهید.
  • اندازه درخواست را اعتبارسنجی کنید.
  • timeout پاسخ را مدیریت کنید.
  • APIها را نسخه‌گذاری کنید.
  • ترافیک را throttle کنید.
  • با service discovery یکپارچه شوید.

از این میان، محبوب‌ترین و مرتبط‌ترین موارد برای مصاحبه‌های طراحی سیستم احراز هویت، Rate Limiting و whitelist یا blacklist کردن IP هستند. اگر می‌خواهید از middleware نام ببرید، فقط مطمئن شوید هدفی دارد و زمان زیادی را روی آن نمی‌گذارید.

پیشنهاد من هنگام وارد کردن API Gateway به طراحی این است که به‌سادگی بگویید: «یک API Gateway برای مدیریت مسیریابی و middlewareهای پایه اضافه می‌کنم» و ادامه بدهید.

۳) مسیریابی

gateway یک جدول مسیریابی نگه می‌دارد که درخواست‌های ورودی را به سرویس‌های backend نگاشت می‌کند. این نگاشت معمولاً بر اساس ترکیبی از این موارد است:

  • مسیرهای URL (مثلاً مسیرهای /users/* به سرویس کاربران می‌روند).
  • متدهای HTTP (مثلاً GET، POST و غیره).
  • پارامترهای query.
  • هدرهای درخواست.

مثلاً یک پیکربندی مسیریابی ساده ممکن است این‌طور باشد:

1
2
3
4
5
6
7
8
9
10
routes:
  - path: /users/*
    service: user-service
    port: 8080
  - path: /orders/*
    service: order-service
    port: 8081
  - path: /payments/*
    service: payment-service
    port: 8082

gateway سریع جستجو می‌کند که بر اساس مسیر، متد، پارامترهای query و هدرها، درخواست را به کدام سرویس backend بفرستد و بر همان اساس درخواست را ارسال می‌کند.

۴) ارتباط با Backend

با این‌که بیشتر سرویس‌ها از طریق HTTP ارتباط می‌گیرند، در بعضی موارد سرویس‌های backend شما ممکن است برای ارتباط داخلی از پروتکل دیگری مثل gRPC استفاده کنند. وقتی این اتفاق می‌افتد، API Gateway می‌تواند ترجمه بین پروتکل‌ها را انجام دهد، هرچند در عمل نسبتاً غیرمعمول است.

پس gateway درخواست را قبل از ارسال به سرویس backend به پروتکل مناسب تبدیل می‌کند. این خوب است، چون به سرویس‌های شما اجازه می‌دهد از هر پروتکل یا قالبی که کارآمدتر است استفاده کنند، بدون این‌که کلاینت‌ها لازم باشد از آن خبر داشته باشند.

۵) تبدیل پاسخ

gateway پاسخ سرویس backend را به قالبی که کلاینت می‌خواهد تبدیل می‌کند. این لایه تبدیل به سرویس‌های داخلی شما اجازه می‌دهد از هر پروتکل یا قالبی که کارآمدتر است استفاده کنند، در حالی که API تمیز و یکدستی به کلاینت‌ها ارائه می‌دهند.

مثلاً:

1
2
3
4
5
6
7
8
9
10
11
12
// Client sends a HTTP GET request
GET /users/123/profile

// API Gateway transforms this into an internal gRPC call
userService.getProfile({ userId: "123" })

// Gateway transforms the gRPC response into JSON and returns it to the client over HTTP
{
  "userId": "123",
  "name": "John Doe",
  "email": "[email protected]"
}

۶) کش

قبل از فرستادن پاسخ به کلاینت، gateway می‌تواند به‌صورت اختیاری پاسخ را کش کند. این برای داده‌هایی مفید است که زیاد دسترسی می‌شوند، زیاد تغییر نمی‌کنند و از همه مهم‌تر مخصوص یک کاربر نیستند. اگر انتظار دارید یک درخواست API برای ورودی مشخص همیشه همان نتیجه را بدهد، کش کردن آن منطقی است.

API Gateway می‌تواند استراتژی‌های مختلف کش را هم پیاده کند. مثلاً:

  • کش پاسخ کامل (Full Response Caching): کل پاسخ را برای endpointهایی که زیاد دسترسی می‌شوند کش کنید.
  • کش جزئی (Partial Caching): بخش‌های مشخصی از پاسخ را که به‌ندرت تغییر می‌کنند کش کنید.
  • Cache Invalidation: از TTL یا invalidation مبتنی بر رویداد استفاده کنید.

در هر مورد می‌توانید پاسخ را در حافظه خود gateway یا در یک کش توزیع‌شده مثل Redis کش کنید.

مقیاس‌دهی API Gateway

هنگام بحث درباره مقیاس‌دهی API Gateway در مصاحبه‌ها، دو بُعد اصلی را باید در نظر بگیرید: مدیریت افزایش بار و مدیریت توزیع جهانی.

مقیاس افقی

ساده‌ترین رویکرد برای مدیریت بار بیشتر مقیاس افقی است. API Gatewayها معمولاً stateless هستند و همین آن‌ها را کاندیدای ایده‌آل مقیاس افقی می‌کند. می‌توانید نمونه‌های gateway بیشتری پشت یک Load Balancer اضافه کنید تا درخواست‌های ورودی توزیع شوند.

با این‌که API Gatewayها عمدتاً به‌خاطر کارکرد مسیریابی و middleware شناخته می‌شوند، اغلب قابلیت‌های Load Balancing هم دارند. با این حال فهمیدن این تمایز مهم است.

  • Load Balancing از کلاینت به gateway: معمولاً یک Load Balancer اختصاصی (مثل AWS ELB یا NGINX) جلوی نمونه‌های API Gateway شما این کار را انجام می‌دهد.
  • Load Balancing از gateway به سرویس: خود API Gateway می‌تواند بین چند نمونه از سرویس‌های backend بار را متعادل کند.

معمولاً در مصاحبه می‌توان این را انتزاعی کرد. کشیدن یک جعبه واحد برای مدیریت «API Gateway و Load Balancer» معمولاً کافی است. نمی‌خواهید در جزئیات نقاط ورودی غرق شوید، چون به احتمال زیاد حواس را از کارکرد اصلی سیستم پرت می‌کنند.

توزیع جهانی

گزینه دیگری که به‌خصوص برای اپلیکیشن‌های بزرگ با کاربرانی که در سراسر دنیا پخش شده‌اند خوب کار می‌کند، مستقر کردن API Gatewayها نزدیک‌تر به کاربران شماست، شبیه نحوه استقرار CDN. این معمولاً شامل این موارد است:

  • استقرار منطقه‌ای: نمونه‌های gateway را در چند ریجن جغرافیایی مستقر کنید.
  • مسیریابی مبتنی بر DNS: از GeoDNS برای هدایت کاربران به نزدیک‌ترین gateway استفاده کنید.
  • همگام‌سازی پیکربندی: مطمئن شوید قوانین و سیاست‌های مسیریابی در همه ریجن‌ها یکدست‌اند.

API Gatewayهای محبوب

نگاهی به محبوب‌ترین API Gatewayها بیندازیم.

سرویس‌های مدیریت‌شده

ارائه‌دهندگان ابر راه‌حل‌های API Gateway کاملاً مدیریت‌شده‌ای ارائه می‌کنند که با اکوسیستم خودشان خوب یکپارچه می‌شود. این آسان‌ترین گزینه است اما هم‌زمان گران‌ترین.

AWS API Gateway:

  • یکپارچگی بدون درز با سرویس‌های AWS.
  • پشتیبانی از REST و WebSocket API.
  • ویژگی‌های داخلی مثل throttling درخواست، کلید API و usage plan، یکپارچگی با AWS Lambda و مانیتورینگ با CloudWatch.

Azure API Management:

  • پشتیبانی قوی از OAuth و OpenID Connect.
  • پیکربندی مبتنی بر سیاست (policy-based).
  • پورتال توسعه‌دهنده برای مستندات API.

Google Cloud Endpoints:

  • یکپارچگی عمیق با سرویس‌های GCP.
  • پشتیبانی قوی از gRPC.
  • مستندات خودکار OpenAPI.

راه‌حل‌های متن‌باز

برای تیم‌هایی که کنترل بیشتری می‌خواهند یا روی زیرساخت خودشان (on-premises) کار می‌کنند:

Kong:

  • بر پایه NGINX ساخته شده.
  • اکوسیستم گسترده افزونه (plugin).
  • از استقرارهای سنتی و service mesh پشتیبانی می‌کند.

Tyk:

  • پشتیبانی بومی از GraphQL.
  • تحلیل داخلی API.
  • قابلیت چند دیتاسنتر.

Express Gateway:

  • مبتنی بر JavaScript و Node.js.
  • سبک و مناسب توسعه‌دهندگان.
  • برای میکروسرویس‌های Node.js مناسب است.

چه زمانی API Gateway پیشنهاد کنیم

بسیار خب، اما کی باید در مصاحبه از API Gateway استفاده کنید؟

خلاصه کوتاه: وقتی معماری میکروسرویس دارید استفاده کنید و وقتی معماری ساده کلاینت و سرور دارید استفاده نکنید.

با معماری میکروسرویس، API Gateway تقریباً ضروری است. بدون آن، کلاینت‌ها باید مستقیم درباره چند سرویس بدانند و با آن‌ها ارتباط بگیرند، که به coupling سخت‌تر و کد کلاینت پیچیده‌تر می‌انجامد. gateway جداسازی تمیزی بین معماری سرویس‌های داخلی و سطح API خارجی شما فراهم می‌کند.

با این حال، تشخیص این‌که API Gateway کی زیادی است هم به همان اندازه مهم است. برای اپلیکیشن‌ها یا سیستم‌های یکپارچه ساده با یک نوع کلاینت، وارد کردن API Gateway پیچیدگی غیرضروری اضافه می‌کند.

این را همه‌جا گفته‌ام، اما می‌خواهم خیلی روشن باشد. با این‌که فهمیدن هر جزئی که وارد طراحی می‌کنید مهم است، API Gateway جالب‌ترین جزء نیست. احتمال این‌که با صرف زمان زیاد روی آن اشتباه کنید خیلی بیشتر از احتمال این است که زمان کافی صرفش نکنید.

آن را کوتاه بگویید: بگویید مسیریابی و middleware را مدیریت می‌کند و ادامه بدهید.