آیا اپلیکیشن ساختهشده با هوش مصنوعی شما به یک بکاند واقعی نیاز دارد؟ چطور قبل از اضافه کردنش بفهمید
شما دقیقاً برای سه چیز به بکاند واقعی نیاز دارید: پردازش پرداختها، دور نگه داشتن کلیدهای API و اطلاعات محرمانه از مرورگر، و عمل کردن بهعنوان منبع واحد حقیقت وقتی چند کاربر همزمان روی یک داده کار میکنند.
لحظهای که شک میکنید
بکاند فقط کدی است که جایی غیر از مرورگر اجرا میشود — کارهایی انجام میدهد که مرورگر نباید انجامشان بدهد، مثل دریافت پول یا نگهداشتن اطلاعات محرمانه، و با یک پایگاه داده صحبت میکند. بیشتر اپلیکیشنهای ساختهشده با هوش مصنوعی از قبل بخشی از این کارها را انجام میدهند، حتی وقتی شبیه چیزی که در ذهن داشتید نیست.
اپلیکیشن شما کار میکند. کاربران ثبتنام میکنند. ویژگیهای جدید منتشر میشوند. بعد آن حس خزنده سراغتان میآید: مگر نباید یک «بکاند واقعی» هم داشته باشد؟ همه از بکاند حرف میزنند. اپلیکیشنهای جدی بکاند دارند. بیلدرتان یک چیز مبتنی بر TypeScript-در-React به شما داده و دارید فکر میکنید شاید این آنقدرها هم… حرفهای نباشد.
حقیقت این است: این حس معمولاً اشتباه است. هیچچیز از کارهایی که بکاند انجام میدهد جادویی نیست، و اپلیکیشن ساختهشده با هوش مصنوعی شما ممکن است از قبل همان کارها را انجام بدهد. اگر نمیدهد، اضافه کردن یک بکاند مشکل واقعی را حل نمیکند — هرچه که واقعاً خراب باشد.
این نوشته دربارهی شناختن این تفاوت است.
بکاند اصلاً برای چه چیزی است؟
بکاند دقیقاً به سه دلیل وجود دارد: مدیریت پول، نگهداشتن امن اطلاعات محرمانه، و عمل کردن بهعنوان منبع واحد حقیقت وقتی بیش از یک نفر روی دادهی یکسانی ویرایش میکند.
مدیریت پول. اگر اپلیکیشن شما پرداخت جمع میکند یا از کاربران هزینه میگیرد، پردازشگر پرداخت حتماً به یک بکاند نیاز دارد. مرورگر شما نمیتواند مستقیم با کلید سری API به Stripe متصل شود (یعنی کلید را در کد سمت کلاینت میگذاشتید، جایی که همه میتوانند ببینندش). پس به یک سرور نیاز دارید که کلید را امن نگه دارد، درخواستها را از مرورگر بگیرد، و از طرف کاربر با Stripe صحبت کند. این یک بکاند است. لازم نیست پیچیده باشد — یک تابع سادهی Node برای بیشتر اپلیکیشنها کافی است — اما باید وجود داشته باشد.
نگهداشتن امن اطلاعات محرمانه. کلیدهای API، رمزهای عبور پایگاهداده، توکنهای احراز هویت — اینها نمیتوانند در مرورگر باشند چون هر کسی که از اپلیکیشن شما استفاده میکند میتواند آنها را بخواند. اگر اپلیکیشن ساختهشده با هوش مصنوعی شما نیاز دارد به یک سرویس خارجی که احراز هویت میخواهد وصل شود، مرورگر تنهایی از پس این کار برنمیآید. اپلیکیشن میتواند با بکاند شما صحبت کند، که کلید را دارد و با سرویس خارجی تماس میگیرد. اطلاعات محرمانهی شما محرمانه میماند.
یک منبع واحد حقیقت برای داده. اگر دو کاربر همزمان از اپلیکیشن شما استفاده میکنند و هر دو در حال تغییر یک دادهی یکسان هستند، به یک مرجع مرکزی نیاز دارید که تصمیم بگیرد تغییر چه کسی برنده میشود. مرورگر نمیتواند داور باشد — دو مرورگر نمیتوانند همدیگر را ببینند. پس به یک سرور نیاز دارید که بگوید «تغییر نام آلیس اعمال میشود، تغییر باب ۳۰ میلیثانیه دیرتر رسیده پس اعمال نمیشود.» آن سرور یک بکاند است. برای همین است که بخش پایگاهداده اهمیت دارد — به یک جا نیاز دارید که همهی داده واقعاً آنجا زندگی کند.
توجه کنید چه چیزی در این لیست نیست: عملکرد، حرفهای بودن، مقیاسپذیری، بهخاطر-اینکه-همه-دارند. اینها همان حسهایی هستند که شما را گول میزنند تا پیچیدگیای اضافه کنید که نیازی به آن ندارید.
چطور بفهمید واقعاً به بکاند نیاز دارید؟
سه نشانه یعنی واقعاً به بکاند نیاز دارید: اپلیکیشن به دلیلی کند است که مرورگر بهتنهایی نمیتواند حلش کند، به کدی نیاز دارید که جایی اجرا شود که کاربر نتواند ببیندش یا قطعش کند، یا دو کاربر دارند دادهی همدیگر را رونویسی میکنند. بگذارید ببینیم کدام یک، اگر هیچکدام، شامل حال شما میشود.
«کند است.» اگر کاربران از کندی گزارش میدهند، معمولاً مشکل یکی از این سه چیز است: مرورگر کار زیادی انجام میدهد (وابسته به CPU، الگوریتم بد، رندر بیشازحد DOM)، شبکه کند است (متأسفانه ولی واقعیت است)، یا پایگاهداده کند است (کوئریهای زیاد، ایندکسهای اشتباه — اپلیکیشن ساختهشده با هوش مصنوعی شما احتمالاً از قبل با یک پایگاهداده، معمولاً خوب، صحبت میکند). یک بکاند واقعی کار CPU در مرورگر را حل نمیکند. یک بکاند واقعی تأخیر شبکه را حل نمیکند (فیزیک سختگیر است). یک بکاند میتواند با اضافهکردن کش یا الگوهای کوئری هوشمندتر به کوئریهای پایگاهداده کمک کند، اما بیلدرتان احتمالاً از قبل به این فکر کرده.
یک داستان واقعی از کندی: یک اپلیکیشن لیستکار در بارگذاری لیست کند بود. توسعهدهنده فکر کرد «به یک بکاند واقعی نیاز دارم.» مشکل واقعی: اپلیکیشن هر بار همهی ۵۰۰۰ آیتم را بارگذاری میکرد، بهجای اینکه فقط ۵۰ تای اول را با دکمهی «بیشتر ببین» بارگذاری کند. در یک بعدازظهر بدون دستزدن به بکاند حل شد. بکاند مشکل نبود.
«میخواهم کدی اجرا کنم که کاربر نباید ببیند.» این تنها دلیلی است که واقعاً منطقی است، و از آنچه فکر میکنید نادرتر است. مثالها: ارسال ایمیل بعد از ثبتنام کاربر (میخواهید آن کد اجرا شود حتی اگر تب را ببندد)، اجرای یک کار پسزمینه که فایلها را شبها پردازش میکند، تماس با یک API خارجی طبق زمانبندی. اینها دلایل معتبری هستند. واقعاً به چیزی نیاز دارید که جایی روی سرور اجرا شود. اما لازم نیست یک بکاند کامل با احراز هویت و مسیریابی و پایگاهداده باشد. میتواند یک «تابع ابری» تکی باشد که طبق زمانبندی اجرا میشود یا با یک وبهوک فراخوانی میشود. خیلی سادهتر از یک بکاند کامل.
«چند کاربر همزمان یک داده را تغییر میدهند و من دارم بهروزرسانیها را از دست میدهم.» این یکی واقعی است. اگر میبینید «ویرایشهای آلیس ناپدید شدند» یا «دو نفر یک فرم را ویرایش کردند و تغییرات نفر دوم روی نفر اول غالب شد،» شما یک مشکل تداخل دارید. بعضی پایگاهدادهها این را بهتر از بقیه مدیریت میکنند، و بعضی بیلدرهای هوش مصنوعی بهطور پیشفرض از پایگاهدادههایی استفاده میکنند که اینطور نیستند. اما راهحل همیشه یک بکاند کامل نیست — ممکن است تغییر پایگاهداده، اضافهکردن قفل، یا اضافهکردن همزمانی خوشبینانه باشد (یک اصطلاح فانتزی برای «شمارهی نسخهی قبلی را نگه دار و قبل از اجازهی بهروزرسانی مقایسه کن»). از بیلدرتان بپرسید آیا میتوانند پایگاهداده را عوض کنند یا ردیابی نسخه اضافه کنند. شاید به بکاند نیاز ندارید؛ به یک تنظیم پایگاهدادهی هوشمندتر نیاز دارید.
چه چیزی شبیه مشکل بکاند بهنظر میرسد، ولی نیست؟
سه چیز اشتباهاً مشکل بکاند تصور میشوند در حالی که نیستند: جاوااسکریپت که همهجایش یکجاست، نبودِ یک لایهی API جدا، و نگرانی امنیتی کلی بدون یک مشکل مشخص.
«کد جاوااسکریپت است و همهاش یکجاست.» بسیاری از اپلیکیشنهای موفق جاوااسکریپت در مرورگر هستند که با یک پایگاهدادهی واقعی صحبت میکنند (Firebase، Supabase، MongoDB Atlas، هرچه که بیلدرتان راهاندازی کرده). هیچ سرور «بکاند واقعی» وجود ندارد. همهچیز کار میکند. اینکه کد در یک زبان و یک جا باشد به این معنی نیست که واقعی نیست. جاوااسکریپت کار میکند.
«لایهی API جدایی وجود ندارد.» مرورگر شما مستقیم با پایگاهدادهتان صحبت میکند. غریزهی اول خیلیها این است که «این درست نیست، باید یک API در وسط باشد.» اما اگر API فقط این باشد که «از این جدول انتخاب کن و برگردان» یا «در این جدول درج کن،» لایهی وسط چیزی اضافه نمیکند. فقط سربار است. پایگاهدادهی شما خودش از قبل یک API است. اگر میتوانید مستقیم صدایش بزنید.
«نگران امنیت هستم.» بیشتر اپلیکیشنهای ساختهشده با هوش مصنوعی با پیشفرضهای معقولی میآیند: رمزهای عبور هش میشوند، تزریق SQL ممکن نیست (کتابخانهی پایگاهداده جلویش را میگیرد)، اطلاعات محرمانه از کلاینت دور نگه داشته میشوند. اگر واقعاً نگران هستید، کار درست این است که از بیلدرتان بپرسید آیا این کارها را انجام میدهند، نه اینکه غریزی یک بکاند اضافه کنید. یک بکاند بد ساختهشده آسیبپذیرتر از یک فرانتاند خوب ساختهشده است.
درخت تصمیم صادقانه
اینجا نحوهی فهمیدن این موضوع بدون حدسزدن است:
۱. آیا اپلیکیشن شما همین حالا، بدون بکاند، میتواند کاری که انجام میدهد را انجام دهد؟ اگر بله، به مرحلهی ۲ بروید. اگر نه، از قبل یک بکاند دارید (یا باید بسازید). ادامه دهید. (اپلیکیشن ساختهشده با هوش مصنوعی شما ممکن است از قبل یکی داشته باشد.)
۲. چیزی که میخواهید اضافه کنید، کاری است که مرورگر اصولاً نمیتواند انجام دهد؟ پول دریافت کند؟ قطعاً. ایمیل بفرستد؟ بله. با کلید سری با یک API خارجی تماس بگیرد؟ بله. چیز دیگری؟ احتمالاً نه. اگر کاری است که مرورگر میتواند انجام دهد اما کند است، به مرحلهی ۳ بروید. اگر کاری است که مرورگر نمیتواند انجام دهد، به بکاند نیاز دارید.
۳. اگر مشکل واقعی را حل کنید، کندی از بین میرود؟ چیزهای کمتری بارگذاری کنید؟ هوشمندانهتر کش کنید؟ درخواستها را دستهای کنید؟ از پایگاهدادهی بهتری استفاده کنید؟ نکته این است: اول بفهمید واقعاً چه چیزی کند است. فقط بعد از تمامکردن راهحلهای واضح بکاند اضافه کنید. چون اضافهکردن بکاند یک الگوریتم کند را حل نمیکند — فقط آن را به یک ماشین دیگر منتقل میکند.
۴. اگر بکاند اضافه کنید، واقعاً مشکل را حل میکند؟ این تله است. بکاند اضافه میکنید تا «عملکرد را بهبود دهید،» و تأخیر بدتر میشود چون حالا دارید تماسهای شبکهای با بکاندتان میگیرید، که تماسهای شبکهای با پایگاهداده میگیرد، کاری که میتوانستید مستقیم از مرورگر با یک جهش انجام دهید. اول اندازهگیری کنید. بعد اضافه کنید.
به یک بکاند کامل نیاز دارید یا فقط یک تابع ابری؟
اگر چیزی که میخواهید داخل یک تابع تکی که چند ثانیه اجرا میشود و بعد متوقف میشود جا میشود، به یک تابع ابری نیاز دارید، نه یک بکاند کامل. این هم یک تست بویایی.
به کاری فکر کنید که میخواهید بکاند انجام دهد. حالا تصور کنید آن را بهصورت یک تابع تکی جاوااسکریپت (شاید ۱۰۰ خط) بنویسید که وقتی فراخوانی میشود چند ثانیه اجرا میشود، بعد متوقف میشود. آیا در آن جعبه جا میشود؟
- وبهوکهای پرداخت را مدیریت کند؟ بله.
- یک ایمیل خوشآمدگویی بفرستد؟ بله.
- یک فایل را قبل از آپلود اعتبارسنجی کند؟ بله.
- یک گزارش شبانه اجرا کند؟ بله (تقریباً — طبق زمانبندی صدایش میزنید).
اگر جواب بله است، به یک «بکاند واقعی» نیاز ندارید. به یک تابع ابری نیاز دارید. Vercel، AWS Lambda، Google Cloud Functions، هرچه. ارزانتر است، سادهتر است، و لازم نیست از یک سرور نگهبانی کنید.
اگر جواب نه است — اگر به چیزی نیاز دارید که همیشه در حال اجراست، هزاران درخواست را مدیریت میکند، با منطق کسبوکار پیچیده — پس دارید به یک بکاند واقعی فکر میکنید و آن گفتگو مهمتر است. اما صادقانه بگویم، این برای اپلیکیشنهایی که مردم با هوش مصنوعی میسازند نادر است. بیشتر آنچه شبیه «کار بکاند» بهنظر میرسد فقط «این API را صدا بزن» یا «این داده را ذخیره کن» است، کاری که بیلدرتان احتمالاً از قبل مدیریت میکند.
سؤال واقعی که باید از بیلدرتان بپرسید
قبل از اینکه چیزی اضافه کنید، از بیلدرتان یک سؤال بپرسید: همین حالا چه چیزی خراب است که یک بکاند واقعاً حلش میکند؟
اگر جواب مشخصی داشته باشند — «باید پول دریافت کنیم،» «باید با کلید سری با یک API تماس بگیریم،» «تداخل داده داریم» — عالی. میدانید دارید به سمت چه چیزی میسازید.
اگر جواب این باشد که «خب، اپلیکیشنهای واقعی بکاند دارند،» این یک حس است، نه یک دلیل. همان حسی است که شما را وادار میکند به اپلیکیشنی که هیچکس با کسی به اشتراک نمیگذارد حساب کاربری اضافه کنید، یا یک اسکیمای پایگاهداده با پانزده جدول بسازید وقتی واقعاً سه چیز دارید. این بوی خزش دامنه است، با کلاه بکاند.
بیشتر اپلیکیشنهای تکنفرهی موفق به معنایی که شما تصور میکنید «بکاند واقعی» ندارند. آنها یک پایگاهداده دارند (بیلدرتان احتمالاً آن را راهاندازی کرده). شاید یک یا دو تابع طبق زمانبندی اجرا شوند. اما کدی که در مرورگر اجرا میشود کار را انجام میدهد، مستقیم با پایگاهداده صحبت میکند، و بدون لایهی وسط ویژگیها را منتشر میکند.
اپلیکیشن شما احتمالاً همینطور که هست خوب است. حسی که میگوید نیست معمولاً صدای بلندپروازی است، نه حقیقت. وقتی یک مشکل واقعی را حل میکند بکاند اضافه کنید، نه چون حس میکنید باید.
دفعهی بعد که دارید یک ویژگی را طراحی میکنید، بپرسید: آیا این چیزی است که مرورگر اصولاً نمیتواند انجام دهد؟ یا چیزی است که فکر میکنید به بکاند نیاز دارد چون این کلمه را آنقدر شنیدهاید؟ جواب این دو سؤال متفاوت است، و فقط یکی از آنها وظیفهی شماست.