پیادهسازی استعلام ثنا: ورودی، خطاها و حالتهای لبهای
برای وصل کردن استعلام ثنا، ورودی را سختگیرانه پاک کنید، خطاها را به رفتار تبدیل کنید، سه حالت خروجی را جدا بگیرید و نتیجه را تاریخدار بدانید.
بیشتر خطاهای استعلام ثنا از خود سرویس نمیآید؛ از اینکه ورودی دقیق نبوده یا دو خروجی منطقی یکی فرض شدهاند. اگر این دو را درست بگیرید، بقیهاش مهندسی معمولی است.
این نوشته برای توسعهدهندهای است که استعلام کد ثنا را در محصولش وصل میکند. فرض میکنیم میدانید ثنا چیست؛ اگر نه، اول این را بخوانید.
ورودی: دو فیلد، هر دو سختگیر
کد ملی
باید ده رقم با رقم کنترلی درست باشد. خطای رقم کنترلی را پیش از فراخوان بگیرید؛ سمت ما هم رد میشود ولی بدون هزینه و با رفتوبرگشت بیدلیل.
موبایل
سرویس ما شماره را به شکل 09XXXXXXXXX میفرستد و ارقام فارسی، صفر ابتدایی و پیششمارهٔ بینالمللی را یکدست میکند. با این حال خودتان هم نرمال کنید. دلیلش این است که اگر کاربر شماره را با فاصله یا خط تیره مینویسد، بهتر است قبل از رسیدن به API پاک شود تا پیام خطا فوری و قابل اصلاح باشد.
شمارهای که پس از نرمالسازی شکل موبایل ایرانی ندارد، بهجای ارسال، سمت شما رد شود.
خطاها را به رفتار تبدیل کنید
از جدول کدهای خطای مستندات API اینها برای ثنا مهماند:
| کد | چه کار کنید |
|---|---|
invalid_input | فیلدها را اصلاح کنید؛ هزینه ندارد |
not_found | پاسخ معتبر است و هزینه دارد؛ آن را «نتیجهٔ مشخص» حساب کنید |
provider_failed_retryable | گذراست؛ با تأخیر دوباره، هزینه ندارد |
temporarily_unavailable | سرویس مرجع در دسترس نیست؛ بعداً |
rate_limited | هدر Retry-After را بخوانید |
insufficient_funds | موجودی را شارژ کنید |
اشتباه رایج: provider_failed_retryable را بینهایت تکرار کردن. یک سقف (مثلاً سه بار با فاصلهٔ فزاینده) بگذارید و بعد خطا را به کاربر بدهید.
دو مقدار منطقی در کد
یک ساختار ساده و پرهیز از شرط تو در تو:
```ts type SanaState = "no_sana" | "mobile_mismatch" | "ok";
function sanaState(r: { registered: boolean; matched: boolean }): SanaState { if (!r.registered) return "no_sana"; return r.matched ? "ok" : "mobile_mismatch"; } ```
سه حالت، سه مسیر در رابط. هر سه را در آزمون واحد بگیرید. حالت «ثبتنام نشده ولی تطابق بله» را عمداً نادیده گرفتهایم چون منطقاً رخ نمیدهد؛ اگر رخ داد، لاگش کنید.
ذخیره: چه چیزی را نگه دارید
نتیجه را با تاریخ نگه دارید، ولی با یک هشدار: وضعیت ثنا عوض میشود. کسی که امروز ثبتنام ندارد، هفتهٔ بعد دارد. یک نتیجهٔ ذخیرهشده را تاریخدار بخوانید و برای تصمیم مهم دوباره بپرسید.
پاسخ شامل کد ملی و موبایل ورودی نمیشود که دوباره در لاگ بنشیند. پیشنهاد میکنیم شما هم آنها را کنار نتیجه ذخیره نکنید مگر جریان کاری لازم داشته باشد. اگر ذخیره میکنید، موبایل را ماسک کنید.
کش و تکرار
سرویس گاهی پاسخ را از کش میدهد؛ فیلدهای source.cached و fetchedAt در پاسخ میگویند. اگر stale درست است یعنی سرویس مرجع در دسترس نبوده و آخرین پاسخ معتبر داده شده. برای تصمیم حساس، پاسخ کهنه را کافی ندانید و fetchedAt را بخوانید.
شما هم برای یک کد ملی و موبایل در یک جریان کاری یک بار استعلام بگیرید و نتیجه را در همان جریان نگه دارید. هر پاسخ معتبر هزینه دارد، پس تکرار بیدلیل پول است.
آزمون
لایهٔ تفسیر را جدا کنید و با پاسخهای ساختگی خودتان آزمون بگیرید. سه پاسخ ساختگی بنویسید (هر سه حالت) و مطمئن شوید رابط برای هر کدام پیام درست میدهد. هیچ مقداری از این آزمونها نباید به داده واقعی کاربر اشاره کند.
آنچه این سرویس نمیکند
مرز کار سرویس در صفحهٔ استعلام ثنا هم نوشته شده است.
ابلاغیه، پرونده و کد ثنا را نشان نمیدهد. دلیل مغایرت موبایل را هم نمیگوید. و تصمیم نمیگیرد که کدام مسیر ابلاغ را انتخاب کنید.
چکلیست قبل از انتشار
- کد ملی و موبایل پیش از ارسال اعتبارسنجی میشوند.
- هر خطا یک رفتار مشخص دارد و هیچ خطایی «خطای نامشخص» نمیشود.
- تکرار خودکار سقف دارد.
- سه حالت خروجی در آزمون واحد پوشش دارند.
- نتیجه تاریخ دارد و برای تصمیم حساس دوباره پرسیده میشود.
- در لاگ کد ملی و موبایل کامل نیست.
requestIdهر پاسخ ذخیره میشود تا پشتیبانی بتواند پیگیری کند.
چرا requestId را نگه دارید
هر پاسخ requestId دارد و اگر مشکلی بود پشتیبانی با آن کار میکند. نگهداشتنش هزینهای ندارد و بدون آن، توضیح اینکه «پریروز یک درخواست خراب بود» تقریباً ناممکن است. آن را کنار نتیجه (نه کد ملی) ذخیره کنید.
همزمانی
اگر بیش از یک بار برای یک کاربر همزمان درخواست میرود (مثلاً دو بار کلیک)، یک قفل ساده بگذارید. هر پاسخ معتبر هزینه دارد و دوبار پرداخت برای یک پاسخ هدر است. دکمه را پس از کلیک غیرفعال کنید و در بکاند هم با یک کلید یکتا (کد ملی بهعلاوهٔ جریان کاری) درخواستهای همزمان را یکی کنید.
حالتهای لبهای که کم دیده میشوند
شماره با پیششمارهٔ بینالمللی
کاربری که شمارهاش را با کد کشور مینویسد باید به همان شکل داخلی برسد. اگر نرمالسازی شما این حالت را نمیگیرد، کاربر مجبور میشود دوبار وارد کند. آزمونی بنویسید که شمارهٔ بینالمللی، با فاصله و با ارقام فارسی، سه ورودی متفاوت ولی یک نتیجه بدهد.
کد ملی با صفر ابتدایی
کد ملی ممکن است با صفر شروع شود. اگر آن را عدد بخوانید و دوباره رشته کنید، صفر میافتد و اعتبارسنجی رقم کنترلی رد میشود. همیشه رشته نگه دارید.
شمارهای که دو بار در دو حساب هست
این استعلام تطابق یک موبایل با یک کد ملی را میگوید. اگر دو کد ملی یک موبایل را دارند، دو استعلام جدا و دو نتیجهٔ جدا میگیرید؛ نتیجهای از یکی را به دیگری تعمیم ندهید.
کنترل خطا در جریانهای طولانی
اگر استعلام ثنا یکی از چند مرحلهٔ یک جریان بلندتر است (مثلاً ثبتنام چندگامی)، پاسخ خطا را بهعنوان یک وضعیت قابلازسرگیری ذخیره کنید، نه یک شکست نهایی. کاربری که بعد از temporarily_unavailable برمیگردد، نباید از ابتدای فرم شروع کند. مرحلهای که به ثنا رسیده را علامت بزنید تا دوباره نپرسید و دوباره هزینه ندهید.
همچنین نتیجهٔ خطای ناموفق را با نتیجهٔ منفی قاطی نکنید. «سرویس در دسترس نبود» با «ثنا ندارد» دو چیز متفاوتاند و ذخیرهکردن اولی بهجای دومی کاربر را به مسیر اشتباه میبرد.
خلاصه برای مرور بعدی
ورودی را سختگیرانه پاک کنید، خطاها را به رفتار تبدیل کنید، سه حالت را جدا بگیرید و نتیجه را تاریخدار بدانید. ظاهراً ساده است و همین چهار چیز بیشتر خرابیها را میگیرد.
راهنماهای مرتبط
پرسش و تجربه کاربران
اگر این راهنما جوابتان را نداد، همینجا بپرسید. پرسشها را تیمملی ایپیآی پاسخ میدهد و هر نظر پیش از انتشار بررسی میشود.
هنوز پرسشی ثبت نشده، اولین نفر باشید.
