Perspectives
کلید API مشترک، بودجه نیست
یک کلید، یک صورتحساب، و هیچ مالکی.
By Ehsan Gazar, ۲۵ شهریور ۱۴۰۵
یکی از اعضای تیم شما کلید یک ارائهدهنده را در سرویسی تازه جایگذاری میکند. همان بار اول کار میکند، و نگرانکننده دقیقاً همین است. سه ماه بعد صورتحساب دو برابر شده و هیچکس نمیتواند بگوید کدام سرویس عامل آن بوده است.
این مشکل صورتحساب نیست. مشکل دری است که وجود ندارد.
یک کلید، چهار تیم
کلید API ارائهدهنده یک توکن حامل (bearer token) است. هر کسی آن را در دست داشته باشد، تا وقتی حساب پول دارد، میتواند هر چیزی را که حساب اجازه دارد فراخوانی کند، و ارائهدهنده نمیپرسد او عضو کدام تیم است.
پس کلید پخش میشود. اول در یک سرویس قرار میگیرد، بعد در سرویس دوم، بعد در یک نوتبوک، و بعد در محیط یک پیمانکار، چون این کار سریعتر از صدور کلیدی تازه بود. هر نسخه همان اختیار نسخهی اصلی را دارد.
حالا ببینید دیگر چه کارهایی از دستتان برنمیآید.
نمیتوانید هزینه را به منبعش نسبت دهید، چون فاکتور برای کل حساب یک عدد است. نمیتوانید برای یک کاربرد سقف بگذارید، مگر اینکه برای همه سقف بگذارید. نمیتوانید نسخهی پیمانکار را ابطال کنید بیآنکه آن دو سرویس از کار بیفتند، پس آن نسخه فعال میماند. و کلیدی که به یک مخزن عمومی راه پیدا کند، میتواند پیش از آنکه کسی هشدار را بخواند، کل موجودی را خرج کند.
هیچکدام از اینها کوتاهی ارائهدهنده نیست. او به شما یک اعتبارنامه فروخته است، و این چیزی جز یک اعتبارنامه نیست. ساختاری که تعیین میکند چه کسی چه مقدار خرج کند، ساختنش بر عهدهی شماست. آسان است که این را فقط روزی بفهمید که آن ساختار باید از قبل وجود میداشت.
سقفی که به خود کلید تعلق دارد
راهحل، صفحهگستردهای نیست که بگوید کدام تیم از کدام کلید استفاده میکند. راهحل این است که خود کلید حامل سقف باشد.
هر کلید در وطن بودجهی خودش را دارد، و این بودجه یا برای کل عمر کلید است یا برای ماه تقویمی. کلیدی که برای یک کار شبانه است، سقف ماهانهای میگیرد که از نو شروع میشود. کلیدی که برای یک کار مشخص به پیمانکار داده میشود، سقفی برای کل عمرش میگیرد و متوقف میشود.
سقف پیش از فراخوانی ارائهدهنده بررسی میشود، پس کلیدی که سهمش را خرج کرده، اصلاً به مدل نمیرسد.
کلیدها در تیمها گروهبندی میشوند، و هر تیم علاوه بر بودجهی کلیدهای درونش، بودجهی خودش را دارد. این همان چیزی را فراهم میکند که از کلید مشترک برنمیآید. میتوانید بگویید این تیم این ماه میتواند این مقدار خرج کند، بیآنکه دربارهی دیگران چیزی بگویید، و بیآنکه یک عدد روی فاکتور تنها مدرک شما باشد.
یک قاعده برای بسیاری غافلگیرکننده است، و درست همینطور هم باید باشد. عضوی که به هیچ تیمی تعلق ندارد به همه چیز دسترسی دارد. پیوستن به یک تیم دامنهی آنچه میبینید و خرج میکنید را محدود میکند، نه اینکه آن را اعطا کند. پس افزودن ساختار همیشه یک محدودیت است و هرگز ارتقای ناخواستهی دسترسی نیست.
پیامهای ردی که راهحل را نام میبرند
بخش جالب کنترل هزینه، خودِ رد کردن نیست. این است که آیا پیام رد، شخص درست را به صفحهی درست میفرستد یا نه.
درگاهی که پاسخ میدهد «پرداخت لازم است» و همانجا متوقف میشود، تقریباً هیچ چیز به شما نگفته است. پشت این وضعیت دستکم سه دلیل متفاوت هست، و اقدام درست برای هر کدام فرق میکند.
برای همین بررسیها به ترتیبی ثابت انجام میشوند، و طراحی در همین ترتیب است. نخست موجودی سازمان بررسی میشود. اگر حساب خالی باشد، هیچ کلیدی نمیتواند خرج کند، هر چه بودجهاش بگوید، و «افزایش موجودی» دستور درست است. سپس بودجهی تیم بررسی میشود. اگر بودجهی تیم تمام شده باشد، رفتن به کلید دیگری در همان تیم چیزی را تغییر نمیدهد، و پیشنهاد آن کسی را در یک دور باطل میچرخاند. بودجهی خود کلید در آخر بررسی میشود.
سپس هر پیام رد، دقیقاً همان چیزی را نام میبرد که به سقفش رسیده است. رد بهخاطر تیم میگوید کدام تیم، چون پیامی که بگوید بودجه تمام شده ولی نگوید بودجهی چه کسی، یعنی یک درخواست پشتیبانی. سقف ماهانه میگوید کی از نو شروع میشود. اگر همان عبارت بودجهی مادامالعمر به کار میرفت، کسی را سراغ بالا بردن سقفی میفرستاد که لازم نبود بالا برود. این اتفاق در روز آخر ماه میافتد، درست لحظهای که مشکل داشت خودبهخود حل میشد.
به همین دلیل، نشانی مبدأ پیش از پول بررسی میشود. اگر به کسی بگویید بودجهاش تمام شده، در حالی که پاسخ واقعی این است که از شبکهی اشتباهی درخواست میفرستد، او را سراغ افزایش موجودی حسابی میفرستید که هیچ مشکلی نداشت.
جایی که کار سقف تمام میشود
بودجه در اینجا شروع یک درخواست را محدود میکند، نه پایان آن را.
بررسی پیش از فراخوانی ارائهدهنده انجام میشود و سنجش مصرف پس از پاسخ او. پس آخرین درخواستی که کلید اجازهی ارسالش را دارد، میتواند آن را از سقفش فراتر ببرد. روی یک کلید واقعی با بودجهی یکصدم سنت، رقم نهایی ۰٫۰۰۰۱۱۲۶۵۸۰ دلار بود.
این عبور از سقف بهاندازهی یک درخواست است، و حداکثرش گرانترین فراخوانی تکیای است که آن کلید میتواند انجام دهد. خطای گرد کردنی نیست که بشود پنهانش کرد، و در خود کدی که آن را پیاده میکند نوشته شده است، نه در یک پانویس. سیستمی که بگوید «بودجه» و منظورش «سقف قطعی» باشد، ادعای کاری را میکند که انجام نمیدهد. نخستین کسی که این را میفهمید، همان کسی بود که به آن اعتماد کرده بود.
آنچه یک در بهتنهایی حل نمیکند
به شما نمیگوید آیا آن هزینه ارزشش را داشت یا نه. انتساب میگوید کدام سرویس پول را خرج کرد؛ فقط شما میتوانید بگویید آن سرویس باید خرج میکرد یا نه.
جلوی تیمی را که حلقهای مینویسد و بودجهی یک ماه را در یک بعدازظهر میسوزاند نمیگیرد. آسیب را به همان کلید و همان ماه محدود میکند. تفاوت یک رخداد با یک پسکاوی (postmortem) همین است، و این با پیشگیری یکی نیست.
و یک سیستم دیگر میان کد شما و ارائهدهنده قرار میدهد، که هزینهای واقعی است و باید هزینه به حساب بیاید.
اعتبارنامهای که نتوانید بهتنهایی برایش سقف بگذارید، هزینهاش را به آن نسبت دهید یا ابطالش کنید، در واقع اعتبارنامه نیست. گذرواژهای مشترک است که صورتحسابی به آن وصل است، و صورتحساب مدتها پس از تصمیمی میرسد که باعثش شده است.