چند خط از من :
با توجه رشد و نیاز روزافزون کاربران معماری های کوچک جوابگو پروژه های بزرگ نیستند. طبق تئوری DDD پروژه بزرگ را به قسمت های کوچک تقسیم می کنیم(تقسیم و غلبه) این کار باعث مدیرت آسانتری میشود.این کار یک سری مزایا و معایب دارد که در حوصله این مقاله خارج است.در مقاله قبلی به صورت خیلی ساده و مفهومی به RabbitMQ پرداختیم.طبق مقاله قبلی در این مقاله هم قصد داریم به صورت ساده و مفهومی API Gateway را توضیح داده و در قالب یک مثال کاربردی آن را پیاده سازی کنیم.اینکه شما مفهوم یک بحث را درک کنید یادگیری و کار با آن به مراتب آسانتر خواهد شد.قبل از شروع نگاهی کلی به معماری monolithic و microservices خواهیم پرداخت و مزایا و معایب هر کدام را به صورت خلاصه بیان خواهیم کرد.
؛ API Gateway به خودی خود مفهوم کاملی نیست و به تنهایی کاربردی ندارد .به عنوان مثال پدال دوچرخه را در نظر بگیرید که به تنهایی نمی تواند کاری انجام دهد !ولی وقتی درون مجموعه ای قرار می گیرد یک وظیفه مشخص را انجام میدهد و مجموعه را کامل میکند.API Gateway بخش کوچک دیگری از microserver patterns است که با قرارگیری در یک مجموعه معنی پیدا میکند.
! سعی میکنیم وارد مبحث DDD نشیم و به صورت سطحی مفاهیم میکروسرویس را بیان کنیم و در آخر در یک مثال مفهومی آن را پیاده سازی کنیم.
! در یک پروژه به صورت 100 درصد لازم نیست از API Gateway استفاده کرد .بسته به نیازمندی های پروژه .میتوانیم از ابزار های مختلف استفاده کنیم.
سورس کد این مقاله رو میتوانید از این ریپازیتوری دانلود کنید.

سناریو زیر را درنظر بگیرد :
فرض کنید قصد انجام یک پروژه فروشگاهی بزرگ را دارید.اپلیکیشن شما باید به user interface های مختلفی مثل android ,IOS ,angular سرویس دهی کند. همچنین اپلیکیشن باید اطلاعات مربوط به محصولات را به صورت REST API برای 3rd party applications فراهم کن. به طور مثال برای یک محصول اطلاعات زیر را باید از سرور بگیریم که میتوان کمتر یا بیشتر از این مقدار باشد.
وقتی از معماری های (single application) monolithic استفاده میکنیم کلاینت با یک درخواست کل اطلاعات رو واکشی میکند به طور مثال با فراخوانی ادرس شبیه زیر داده ها درون یک آبجکت نسبتا بزرگ برگشت داده خواهد شد .
GET api.company.com/productdetails/{productId}
وقتی این درخواست داده میشود دورن اپلیکیشن سرویس های مختلفی برای گرفتن داده اجرا میشوند .برای مثال سرویس مربوط به تاریخچه ، تعداد فروش ، نظرات کاربران و ....
مزایا :
معایب:

برای پروژه های بزرگ با درخواست های زیاد معماری های monolithic پاسخگو نیستند. microserver patterns پروژه را به قسمت های مختلف شکسته که هر قسمت به صورت انحصاری وظیفه خودش را انجام می دهد این معماری مشابه monolithic یک سری مزایا و معایب دارد:
مزایا :
معایب :
Microservice Vs Monolith Architecture

؛ Api Gateway چیست ؟
تا اینجای کار به صورت کلی دو معماری microservices و monolithic مورد مقایسه قرار دادیم. طبق سناریو گفته شده پروژه را میتوان به sub domain های مختلف تقسیم کرد . sub domian ها می توانند بدون هیچ وابستگی بر روی هاست های مختلف قرار بگیرند.در این صورت کلاینت ها برای fetch کردن داده باید یک تا چند درخواست را به سرور های مختلف ارسال کنند این کار باعث پیچیدگی زیادی در سطح کلاینت میشود . مثال بالا را در نظر بگیرید که برای واکشی داده ها به شکل زیر عمل میکنیم
؛ API Gateway مانند پل ارتباطی بین کلاینت ها و sub domain های مختلف قرار میگیرد.در این صورت کلاینت ها یک درخواست را برای API Gateway ارسال کرده و API Gateway طبق درخواست سرویس های sub domian های مختلف را فراخوانی می کند.
اگه با الگو facade آشنایی داشته باشید , در الگو facade مجموعه از سرویس ها را درون یک سرویس مشخص می نویسیم و بجای فراخوانی سرویس های متعدد یک سرویس مشخص را فراخوانی می کنیم .API Gateway هم حالت مشابهی دارد شما به جای فراخوانی sub domain های مختلف یک سرویس (API Gateway ) را فراخوانی می کنید.
چرا باید از API Gateway استفاده کنیم :
همانطور که گفته شد عدم استفاده از API Gateway کلاینت ها برای گرفتن داده باید درخواست های متعددی به سرور های مختلف ارسال کنند علاوه بر این نیازمندی های کلاینت های مختلف می تواند با هم متفاوت باشند.یکی دیگر از مشکلاتی که ممکن از به وجود بیایید هنگام آپدیت وب سرویس های مختلف کل کلاینت ها باید آپدیت شوند که کار سخت زمانبری است و درصد خطای بالایی دارد.
؛ API Gateway علاوه بر مزایایی که دارند پیاده سازی ان نسبتا دشوار بوده و درصورت از کار فتادن لایه API Gateway کل درخواست های کلاینت ها مختل میشود .
اگر دقت کرده باشید در ترمینال های مسافرتی سالن هایی با عنوان gateway 1 ، gateway 2 , ... (یا نام های مشابه) را مشاهده کرده اید .هر سالن شما را به ورودی سواری مورد نظر هدایت می کند این کار باعث میشود که جابه جایی مسافرها به صورت منظم تر و با سرعت بیشتری انجام شود.اگر یک سالن وجود داشت به مراتب سرعت کندتر و مدیریت سخت تر خواهد داشت.
شروع به کد :
تا اینجای کار درباره API Gateway به صورت کلی صحبت کردیم در ادمه قصد داریم به صورت یک مثال ساده API Gateway را در پروژه پیاده سازی کنیم.طبق معمول از dotnet برای پیاده سازی استفاده خواهیم کرد.
قصد پیاده سازی سیستم مربوط به دانشگاه داریم ابتدا باید نیازمندی های سیستم را مشخص کنیم .
نیازمندی ها :
نیاز های پروژه بسته به business پروژه تعیین میشود. در این مثال سعی کردیم ساده ترین حالت را در نظر بگیریم.مرحله بعدی پیدا کردن sub domain ها خواهد بود شاید سخت ترین قسمت کار مشخص کردن sub domain باشد.این کار تجربی بوده و باید بسته به business پروژه بخش های پروژه را باید به واحد های کوچک بدون وابستگی به هم تقسیم کنیم.
هدف اصلی که سیستم برای آن ایجاد میشود به عنوان Core Domian شناخته میشود .
در مثال بالا ما student و course را دو میکروسرویس جدا در نظر میگیریم.با صحبت های گفته شده دو میکروسرویس student و course خواهیم داشت همچنین یک API Gateway برای برقراری ارتباط بین کلاینت و میکروسرویس ها ایجاد خواهیم کرد.

یک solution ساخته سه پروژه به شکل زیر ایجاد کنید

توجه کنید با توجه به صحبت های گفته شده هر microservice میتواند منحصر به فرد از microservice های دیگر دیتابیس های مختلفی داشته باشند حتی شما میتوانید از زبان برنامه نویسی معماری های مختلفی در پیاده سازی استفاه کنید.
.برای راحتی کار ما از دیتابیس in memory استفاده می کنیم.
پس مشخص شدن نیازمندی ها و تشخیص ساختار پروژه سراغ کد نویسی میرویم . کد های مربوط به هر sub domain را پیاده سازی کنید در این مثال ما سرویس های CRUD را برای هر sub domain پیاده سازی می کنیم.
تا اینجا کار توانستم نیازمندی های را مشخص کنیم و طبق business کار پروژه را به دو sub domain مختلف تقسیم کنیم درون هر sub domain سرویس های CRUD را پیاده سازی کردیم.برای نمایش خروجی تا به اینجای کار پروژه را اجرا کنید.
برای اجرا پروژه بر روی solution کلیک راست کنید و گزینه properties را انتخاب کنید و در حالت multiple startup projects دو پروژه Course.Microservice را Student.Miroservice را به حالت start در آورید و پروژه را اجرا کنید.
! برای راحتی کار بر روی هر پروژه swagger نصب شده است که به صورت پیشفرض هنگام استارت پروژه اجرا میشود
پس از اجرا پروژه دو صفحه با پورت مختلف اجرا می شوند . می توان گفت سخت ترین بخش تا این قسمت شناسایی sub domain ها بوده! چون هر sub domain کد ها شبیه معماری monolithic را دارد!البته در طبق صحبت های گفته شده هر Miroservice میتواند به هر روشی پیاده سازی شود.
! چالشی که در این قسمت خواهیم داشت همزمانی دیتا بین دیتابیس های مربوط به هر sub domain است که در مقاله های بعدی به این موضوع می پردازیم.
وارد پروژه gateway شوید .در این قسمت قصد داریم درخواست های مربوط به هر کلاینت را مدیریت کنیم.برای ارتباط gateway با Miroservice روش ها و کتابخانه های زیادی وجود دارد. ما از Ocelot استفاده می کنیم.
؛Ocelot یک API Gateway متنباز برای .net که توسط مایکروسافت توسعه داده شده است با Ocelot کلاینت ها دیگر نگران کار با Miroserviceهای مختلف نیستند کاری که Ocelot انجام میدهد گرفتن درخواست http مربوط به کلاینت ها و فرستادن به Miroservice مناسب است.
؛Ocelot برای نسخه های core موجود است و شما در .net استاندارد نمی توانید استفاده کنید
در API Gateway دو مفهوم کلی وجود دارد :
؛ Upstream : به درخواستی که از کلاینت به Api Gateway ارسال میشود.
؛ Downstream : به درخواستی که از Api Gateway به Miroserviceها ارسال میشود گفته میشود
In this way, Ocelot API Gateway will be able to re-route various requests from client to all the involved Microservices.

؛ Ocelot چه کار هایی میتواند انجام دهد :
برای نصب Ocelot میتوانید از nuget یا به صورت زیر نصب کنید
Install-Package Ocelot
وارد پروژه Api Gateway شوید بعد از نصب Ocelot در دو کلاس Program.cs و Startup.cs تنظیمات لازمه را انجام دهید .
اگه به Program.cs دقت کنید Ocelot با یک فایل جیسونی کانفیگ می شوید.فایلی به نام Ocelot.json دورن روت پروژه ایجاد کنید.و به صورت زیر کانفیگ کنید
"Routes": [ { "DownstreamPathTemplate": "/api/student", "DownstreamScheme": "https", "DownstreamHostAndPorts": [ { "Host": "localhost", "Port": 44391 } ], "UpstreamPathTemplate": "/gateway/student", "UpstreamHttpMethod": [ "POST", "PUT", "GET" ] } ] }
در Ocelot.json یک آبجکت با یک سری پراپرتی ها ساخته ایم که بیان کننده ادرس Microsrviceهای مختلف هست.در مثال بالا ادرس get میکروسرویس student را پیاده سازی کرده ایم.پراپرتی های هر قسمت واضح و نیاز به توضحات اضافه ندارند.
؛ postman را باز کنید و آدرس زیر را به صورت get فراخوانی کنید.
https://localhost:44352/gateway/student
با فراخوانی ادرس بالا درخواست به صورت Upstream به Gatewayارسال شده و درون Gateway با کانفیگ های لحاظ شده به صورت Downstream به میکروسرویس مورد نظر ارسال میشود.
بقیه route ها هم به صورت الگو بالا پیاده سازی کنید.
برای تست بقیه api service ها میتوانید این فایل را در postman باز کرده و تست خود را انجام دهید
سخن اخر :
در این مقاله به صورت کلی و ساده درباره میکروسرویس ها صحبت کردیم مزایا و معایب ان را بیان کردیم در ادامه به صورت جزیی تری وارد API Gateway شدیم و در قالب یک مثال ساده آن را پیاده سازی کردیم.هدف این مقاله آشنایی به مفهوم API Gateway بوده و سعی کردیم زیاد وارد جزئیات نشویم .هدف بر این است در مقالات بعدی اجزای دیگر microservices patern را در همین سبک بیان کنیم.
با تشکر از شرکت آسا برای وقتی که برای تهیه این مقاله بهم دادن.
اگه از مقاله راضی بودید میتونید از لینک زیر برام قهوه بخرید : )
https://www.coffeete.ir/sobhan
منابع :
https://www.nginx.com/blog/building-microservices-using-an-api-gateway/
https://code-maze.com/api-gateway-pattern-dotnet-encapsulate-microservices/
https://codewithmukesh.com/blog/microservice-architecture-in-aspnet-core/
https://geekflare.com/api-gateway/
https://www.nginx.com/blog/building-microservices-using-an-api-gateway/