နားလည်ထားရမယ့် အချက်
အမှန်တကယ် integration တစ်ခုသည် API ကို ခေါ်ပြီး 200 OK အမြဲရမည်ဟု မျှော်လင့်ရုံဖြင့် မလုံလောက်ပါ။ rate limit ဖြစ်သည့် request၊ သက်တမ်းကုန်သွားသော token၊ server ခဏတာ ပြဿနာဖြစ်ခြင်း စသည့် ရှုပ်ထွေးသော အလယ်ပိုင်းကို ရှင်သန်နိုင်ရမည်။
ဤလေ့ကျင့်ခန်းသည် ဤသင်တန်းမှ skill နှစ်ခု — retry-with-backoff နှင့် ရှင်းလင်းသော error ဆက်သွယ်ရေး — ကို ပြန်သုံးနိုင်သော code အပိုင်းငယ်တစ်ခု၊ API call wrapper တစ်ခုအဖြစ် ပေါင်းစပ်ထားသည်။
wrapper ၏ တာဝန်မှာ application နှင့် raw API call ကြားတွင် ရပ်တည်ပြီး ပြန်လာသမျှကို အောင်မြင်သော ရလဒ် သို့မဟုတ် user တစ်ဦးက အမှန်တကယ် နားလည်နိုင်သော message တစ်ခုအဖြစ် ပြောင်းပေးရန် ဖြစ်သည်။ "Error: 429" က end user အတွက် ဘာမှ အဓိပ္ပာယ်မရှိပါ၊ "အနည်းငယ်အလုပ်များနေပါသည်..." ကမူ အဓိပ္ပာယ်ရှိသည်။
| Status | wrapper က ထပ်ကြိုးစားသင့်သလား? |
|---|---|
| 429 / 500 | ဟုတ်သည် — များသောအားဖြင့် ယာယီသာဖြစ်တတ်သည်၊ backoff ဖြင့် စောင့်ပြီး ထပ်ကြိုးစားပါ။ |
| 401 / 403 | မဟုတ်ပါ — request ကို ပြင်ရမည်၊ ထပ်ခါထပ်ခါ ခေါ်ရုံနှင့် မပြေပါ။ |
| 404 | မဟုတ်ပါ — resource မရှိပါ၊ ထပ်ကြိုးစားခြင်းက ၎င်းကို ဖန်တီးမပေးနိုင်ပါ။ |
retry ကို အမြဲ ကန့်သတ်ထားပါ
အမှန်တကယ် ပျက်နေသော service တစ်ခုကို ကန့်သတ်မထားသော retry loop ဖြင့် ထိုးနှက်ခြင်းသည် application ကို အကန့်အသတ်မရှိ ရပ်တန့်စေနိုင်ပြီး ဒုက္ခရောက်နေသော service ကို ပိုမိုပျက်စီးစေနိုင်သည်။ maximum retry count တစ်ခုက နှစ်ဖက်လုံးကို ကာကွယ်ပေးသည်။
REQUEST HANDLING STATE MACHINE
------------------------------
LOADING
|
v
call mockApiCall() --> returns one status code
|
|-- 200 --> SUCCESS (show the data, done)
|-- 401 --> NEEDS AUTH (ask user to sign in again, done)
|-- 403 --> FORBIDDEN (explain no access, done)
|-- 404 --> NOT FOUND (explain missing item, done)
|
|-- 429 --> retries left?
| |-- yes --> wait (backoff) --> back to LOADING
| |-- no --> GIVE UP (ask user to retry later)
|
|-- 500 --> retries left?
|-- yes --> wait (backoff) --> back to LOADING
|-- no --> GIVE UP (ask user to retry later)လက်တွေ့ scenario နဲ့ ချိတ်ကြည့်မယ်
callWithHandling(mockApiCall) ကို တည်ဆောက်ပါမည် — ဤ function သည် ကြိုတင်ရေးထားသော mock API ကို ခေါ်ပြီး ၎င်းတွေ့နိုင်သည့် status အားလုံးအတွက် ရင်းနှီးသော ရလဒ်တစ်ခု ပြန်ပေးသည်။
Deterministic Mock တည်ဆောက်ပါ
createMockApiCall(statusSequence) သည် ခေါ်တိုင်း array ထဲမှ နောက်ထပ် status code ပြန်ပေးသည့် function တစ်ခု ပြန်ပေးသည် — network မတည်ငြိမ်မှု မပါ၊ ရလဒ်ကို အတိအကျ ပြန်ဖန်တီးနိုင်သည်။
အဆုံးသတ် States များကို ချက်ချင်း ကိုင်တွယ်ပါ
200 ရလျှင် ချက်ချင်း success ပြန်ပေးပါ။ 401၊ 403 သို့မဟုတ် 404 ရလျှင် ထပ်ကြိုးစားခြင်းမပြုဘဲ ချက်ချင်း သီးခြား message ပြန်ပေးပါ၊ အကြောင်းမှာ ထပ်ကြိုးစားခြင်းက ဤရလဒ်များကို မပြောင်းလဲနိုင်သောကြောင့်ဖြစ်သည်။
429 နှင့် 500 ကို Backoff ဖြင့် ထပ်ကြိုးစားပါ
ကြိုးစားခွင့် ကျန်ရှိပါက ထပ်ကြိုးစားတိုင်း နှစ်ဆတိုးသော delay တစ်ခု (exponential backoff) စောင့်ပြီး ထပ်ကြိုးစားပါ။ ဒုက္ခရောက်နေသော service ကို ချက်ချင်းမထိုးနှက်ဘဲ ပြန်လည်နာလန်ထူနိုင်ရန် အားပေးသည်။
Budget ကုန်ချိန်တွင် သပ်ရပ်စွာ လက်လျှော့ပါ
maxRetries ကျော်လွန်သွားလျှင် အကန့်အသတ်မရှိ loop လုပ်ခြင်း သို့မဟုတ် ကိုင်တွယ်မထားသော error တစ်ခု ပစ်ခြင်းအစား ရှင်းလင်းသော "နောက်မှ ထပ်ကြိုးစားပါ" message ပြန်ပေးပါ။
scenario သုံးခု — rate-limit ပြီး success ဖြစ်ခြင်း၊ auth failure၊ server error ဆက်တိုက်ဖြစ်ခြင်း — ကို run ကြည့်ပါက function တစ်ခုတည်းက မတူညီသော မှန်ကန်သည့် ရလဒ်သုံးမျိုး ထုတ်ပေးသည်ကို တွေ့ရမည်။
အတူတူ စမ်းရေးကြည့်မယ်
function sleep(ms) {
return new Promise((resolve) => setTimeout(resolve, ms));
}
// Builds a deterministic mock API call: each call returns the next
// status code in a fixed, pre-scripted sequence.
function createMockApiCall(statusSequence) {
let index = 0;
return function mockApiCall() {
const status = statusSequence[Math.min(index, statusSequence.length - 1)];
index++;
return { status };
};
}
async function callWithHandling(mockApiCall, options = {}) {
const maxRetries = options.maxRetries ?? 3;
const initialDelayMs = options.initialDelayMs ?? 50;
const log = [];
let delay = initialDelayMs;
for (let attempt = 1; attempt <= maxRetries + 1; attempt++) {
const response = mockApiCall();
log.push(`Attempt ${attempt}: received ${response.status}`);
if (response.status === 200) {
log.push("Result: success.");
return { ok: true, message: "Loaded successfully.", attempts: attempt, log };
}
if (response.status === 401) {
log.push("Result: stopped (not retryable).");
return { ok: false, message: "Please sign in again.", attempts: attempt, log };
}
if (response.status === 403) {
log.push("Result: stopped (not retryable).");
return { ok: false, message: "You don't have access to this.", attempts: attempt, log };
}
if (response.status === 404) {
log.push("Result: stopped (not retryable).");
return { ok: false, message: "That item couldn't be found.", attempts: attempt, log };
}
if (response.status === 429 || response.status === 500) {
const label = response.status === 429 ? "rate limited" : "server error";
if (attempt > maxRetries) {
log.push("Result: gave up after max retries.");
const msg =
response.status === 429
? "Still busy after several tries. Please try again shortly."
: "The service is having trouble. Please try again shortly.";
return { ok: false, message: msg, attempts: attempt, log };
}
log.push(`Result: ${label}, backing off ${delay}ms then retrying.`);
await sleep(delay);
delay *= 2; // exponential backoff
continue;
}
log.push("Result: stopped (unrecognized status).");
return { ok: false, message: "Something unexpected happened.", attempts: attempt, log };
}
}
async function main() {
console.log("--- Scenario A: rate limited twice, then succeeds ---");
const callA = createMockApiCall([429, 429, 200]);
const resultA = await callWithHandling(callA, { maxRetries: 3, initialDelayMs: 20 });
console.log(resultA.log.join("\n"));
console.log(`Final: ok=${resultA.ok} message="${resultA.message}" attempts=${resultA.attempts}`);
console.log("\n--- Scenario B: needs auth ---");
const callB = createMockApiCall([401]);
const resultB = await callWithHandling(callB, { maxRetries: 3, initialDelayMs: 20 });
console.log(resultB.log.join("\n"));
console.log(`Final: ok=${resultB.ok} message="${resultB.message}" attempts=${resultB.attempts}`);
console.log("\n--- Scenario C: server errors exceed retry budget ---");
const callC = createMockApiCall([500, 500, 500, 500]);
const resultC = await callWithHandling(callC, { maxRetries: 2, initialDelayMs: 20 });
console.log(resultC.log.join("\n"));
console.log(`Final: ok=${resultC.ok} message="${resultC.message}" attempts=${resultC.attempts}`);
}
main();--- Scenario A: နှစ်ကြိမ် rate limit ဖြစ်ပြီး success ဖြစ်ခြင်း ---
Attempt 1: received 429
Result: rate limited, backing off 20ms then retrying.
Attempt 2: received 429
Result: rate limited, backing off 40ms then retrying.
Attempt 3: received 200
Result: success.
Final: ok=true message="Loaded successfully." attempts=3
--- Scenario B: auth လိုအပ်ခြင်း ---
Attempt 1: received 401
Result: stopped (not retryable).
Final: ok=false message="Please sign in again." attempts=1
--- Scenario C: server error retry budget ကျော်လွန်ခြင်း ---
Attempt 1: received 500
Result: server error, backing off 20ms then retrying.
Attempt 2: received 500
Result: server error, backing off 40ms then retrying.
Attempt 3: received 500
Result: gave up after max retries.
Final: ok=false message="The service is having trouble. Please try again shortly." attempts=3
(output သည် node lesson2.js ကို actual run ချထားခြင်းမှ ရရှိသည့် တကယ့် output ဖြစ်သည်)၅ မိနစ် စမ်းကြည့်
callWithHandling ကို ချဲ့ကားပြီး 403 ("forbidden") အတွက် 401 ("needs auth") နှင့် ကွဲပြားသော message ရှင်းရှင်းလင်းလင်း log လုပ်ပါ — ဤနှစ်ခုကို မကြာခဏ ရှုပ်ထွေးတတ်သော်လည်း user ကို ပြသရမည့် လမ်းညွှန်ချက် မတူညီပါ။ ထို့နောက် createMockApiCall([500, 429, 500, 200]) ကို maxRetries: 3 ဖြင့် scenario လေးခုမြောက်အဖြစ် ဖန်တီးပြီး run ပါ၊ actual output ကို မကြည့်မီ attempt အရေအတွက်နှင့် final message ကို ကြိုတင်ခန့်မှန်းကြည့်ပါ။
သတိလေးတစ်ချက်
401/403/404 အပါအဝင် failure တိုင်းကို တူညီသောနည်းဖြင့် ထပ်ကြိုးစားခြင်း — ထပ်ကြိုးစားခြင်းက ဘယ်တော့မှ မပြင်နိုင်သော error များအတွက် အချိန်နှင့် rate-limit quota ကို ဖြုန်းတီးရာ ရောက်သည်။
backoff မလုပ်ဘဲ ပုံသေ retry delay သုံးခြင်း — ဒုက္ခရောက်နေသော service ကို ပုံသေ interval ဖြင့် ဆက်တိုက်ထိုးနှက်ခြင်းက ပြန်လည်နာလန်ထူမှုကို ပိုခက်ခဲစေသည်။
MDN — Using the Fetch API (error handling patterns) — API Integration & Webhooks
API Integration Glossary — အသုံးများသော ဝေါဟာရများ
| Term | အဓိပ္ပာယ် |
|---|---|
| Timeout | client တစ်ခုက response ကို ဘယ်လောက်ကြာကြာ စောင့်မည်ဟု ကန့်သတ်ထားသော အချိန်ကန့်သတ်ချက်။ |
| Retry | failure တစ်ခုပြီးနောက် request တူတူကို ထပ်ပို့ခြင်း၊ ပုံမှန်အားဖြင့် ယာယီသာဖြစ်နိုင်သော failure များအတွက်သာ။ |
| Backoff | ချက်ချင်း ထပ်ကြိုးစားမည့်အစား retry တစ်ကြိမ်ချင်းစီကြား တဖြည်းဖြည်း ကြာမြင့်စွာ စောင့်ခြင်း။ |
| Jitter | backoff delay အား ထပ်ထည့်ထားသော သေးငယ်သည့် random ပမာဏ၊ client များစွာက တစ်ပြိုင်နက် ထပ်ကြိုးစားမှုများ တစ်ချိန်တည်း တိုက်မိခြင်းကို ရှောင်ရှားရန်။ |
| Idempotency | operation တစ်ခုသည် ဘယ်နှစ်ကြိမ် ဘေးကင်းစွာ ထပ်လုပ်လုပ် ရလဒ်တူတူ ရရှိသည့် သဘောသဘာဝ။ |
| Idempotency Key | server က မတော်တဆ ထပ်နေသော request ကို မှတ်မိပြီး ဘေးကင်းစွာ လျစ်လျူရှုနိုင်ရန် request တစ်ခုနှင့်အတူ ပို့သော ထူးခြားသည့် တန်ဖိုး။ |
| Secret Management | API key၊ token နှင့် password များကို code သို့မဟုတ် log ထဲ ပေါ်မသွားအောင် သိမ်းဆည်းကိုင်တွယ်သည့် အလေ့အထ။ |
| Environment Variable | codebase အပြင်ဘက်တွင် သတ်မှတ်ထားသော တန်ဖိုး (secret သို့မဟုတ် config setting ကဲ့သို့) ကို program run သည့်အချိန် ဖတ်ယူသည်။ |
| Response Validation | response ကို အသုံးမပြုမီ code က မျှော်လင့်ထားသော field များနှင့် ပုံစံ အမှန်တကယ်ရှိမရှိ စစ်ဆေးခြင်း။ |
| SDK | provider တစ်ခုမှ ကြိုတင်ရေးထားသော library တစ်ခု၊ ၎င်းတို့၏ raw API ကို ပိုမိုလွယ်ကူသော function များဖြင့် wrap ထားသည်။ |
| Webhook | provider တစ်ခုတွင် register လုပ်ထားသော URL တစ်ခု၊ event တစ်ခု ဖြစ်ပွားလိုက်သည်နှင့် polling မလုပ်ဘဲ HTTP request တစ်ခု ချက်ချင်း ပို့ပေးနိုင်ရန်။ |
| Webhook Payload | webhook request တစ်ခုက သယ်ဆောင်လာသော JSON body၊ ဘာ event ဖြစ်ခဲ့သည်နှင့် အသေးစိတ်ကို ဖော်ပြသည်။ |
| Webhook Signature | webhook request တွင် ပါဝင်သော cryptographic တန်ဖိုးတစ်ခု၊ ၎င်းက provider ထံမှ အစစ်အမှန် ပို့ခြင်းဟု သက်သေပြနိုင်စေသည်။ |
| HMAC | Hash-based Message Authentication Code — webhook signature များ ထုတ်ပြီး စစ်ဆေးရန် shared secret တစ်ခုနှင့်အတူ အသုံးများသော algorithm။ |
| Replay Attack | အရင်က မှန်ကန်ခဲ့သော request တစ်ခုကို ဖမ်းယူထားပြီး system ကို အသစ်တစ်ခုအဖြစ် ထပ်လုပ်စေရန် လှည့်စားခြင်း။ |
| Webhook Retry | endpoint က ပထမအကြိမ် အောင်မြင်စွာ response မပြန်ခဲ့လျှင် provider ကိုယ်တိုင် webhook ကို ထပ်ပို့ပေးခြင်း။ |
| Polling | webhook လက်ခံမည့်အစား API ကို "ဘာများ ပြောင်းလဲသလဲ" ဟု အချိန်ဇယားအလိုက် ထပ်ခါထပ်ခါ မေးမြန်းခြင်း။ |
| Rate Limit Headers | 429 မမှီခင် request quota ဘယ်လောက် ကျန်ကြောင်း ပြောပြသော response header များ (ဥပမာ X-RateLimit-Remaining)။ |
| Postman Environment | Postman ထဲက variable အစုအဝေးတစ်ခု (base URL သို့မဟုတ် token ကဲ့သို့) ကို dev နှင့် production ကြား ပြောင်းလဲသုံးနိုင်ခြင်း။ |
| Postman Collection | Postman ထဲတွင် သိမ်းဆည်းစီစဉ်ထားသော request အစုအဝေးတစ်ခု၊ ဝေမျှခြင်း၊ ပြန်သုံးခြင်း သို့မဟုတ် အတူတကွ run ခြင်း ပြုလုပ်နိုင်သည်။ |
| Test Case | integration တစ်ခုသည် အခြေအနေတစ်ခုအောက်တွင် မှန်ကန်စွာ လုပ်ဆောင်သလား စစ်ဆေးရန် သုံးသော မျှော်လင့်ရလဒ်ပါ သီးခြား scenario တစ်ခု။ |
| Automated API Testing | လက်ဖြင့် အကြိမ်တိုင်း စစ်ဆေးမည့်အစား API ကို test case များဖြင့် အလိုအလျောက် (Postman collection သို့မဟုတ် script ဖြင့်) run ခြင်း။ |
| API Documentation | provider တစ်ခု၏ API ကို ဘယ်လိုခေါ်ရမည်ဟု ဖော်ပြထားသော ရေးသားထားသည့် reference — endpoint၊ auth၊ parameters၊ responses နှင့် errors။ |
| API Documentation Checklist | API အသစ်တစ်ခု၏ မှတ်တမ်းတွင် ရှာရမည့် ပုံသေအချက်များ (base URL၊ auth၊ endpoint၊ params၊ headers၊ body၊ response၊ errors၊ rate limit)။ |
| Third-Party API | integrate လုပ်နေသော company နှင့် မတူညီသော company တစ်ခုက ပိုင်ဆိုင်၍ လည်ပတ်နေသော API။ |
| Backend Proxy | frontend နှင့် third-party API ကြားရှိ ကိုယ်ပိုင် server တစ်ခု၊ secret များကို server ဘက်တွင်သာ ထားရှိပြီး browser သို့ မရောက်စေရန်။ |
| Credential | system တစ်ခုသို့ identity သို့မဟုတ် authorization သက်သေပြရန် သုံးသော secret တန်ဖိုးတစ်ခု (API key၊ token၊ password)။ |
| Cache | တူညီသော data အတွက် request ထပ်လုပ်ရန် API ကို ထပ်မခေါ်ရအောင် သိမ်းထားသော response ၏ ယာယီ ကိုယ်ပိုင်မိတ္တူ။ |
| Monitoring | integration တစ်ခု၏ ကျန်းမာရေး (error rate၊ latency၊ failure) ကို ဆက်တိုက် စောင့်ကြည့်ခြင်း၊ user များ တိုင်ကြားမီ ပြဿနာကို တွေ့ရှိနိုင်ရန်။ |
| API Version | API ၏ ကြိုးဆောင်ဆက်ဆံပုံနှင့် ပုံစံ မည်သည့် revision ကို ခေါ်နေသည်ကို ဖော်ပြသော label (v1, v2 ကဲ့သို့)။ |
| Deprecation | API version သို့မဟုတ် feature တစ်ခု နောင်တစ်ချိန်တွင် အလုပ်မလုပ်တော့ကြောင်း တရားဝင် အသိပေးချက်၊ integration များ ကြိုတင် migrate လုပ်ရန် လိုအပ်သည်။ |
| Bearer Token (refresher) | Authorization header တွင် "Bearer <token>" အဖြစ် ပို့သော credential — ၎င်းကို ကိုင်ဆောင်သူကို authenticated ဟု သတ်မှတ်သည်။ |
| API Key (refresher) | ခေါ်ဆိုနေသော application ကို ခွဲခြားသတ်မှတ်ပြီး authorize ပြုသော ရိုးရှင်း၊ ပုံသေ credential တစ်ခု၊ ပုံမှန်အားဖြင့် header သို့မဟုတ် query parameter အဖြစ် ပို့သည်။ |
| Authentication vs Authorization (refresher) | Authentication က ခေါ်ဆိုသူ ဘယ်သူဖြစ်ကြောင်း သက်သေပြသည်၊ authorization က ထိုသူ ဘာလုပ်ခွင့်ရှိသည်ကို ဆုံးဖြတ်သည်။ |
API Integration & Troubleshooting Checklist
| အခြေအနေ | လုပ်ဆောင်ရန် |
|---|---|
| A request keeps timing out | သင့်လျော်သော timeout သတ်မှတ်ထားကြောင်း သေချာစစ်ပါ (အကန့်အသတ်မရှိ မစောင့်ပါနှင့်)၊ ချက်ချင်း loop ဖြင့် ထပ်ကြိုးစားမည့်အစား retry-with-backoff သုံးပါ။ |
| You got a 429 Too Many Requests | backoff ဖြင့် တိုးမြှင့်သော delay ဖြင့် ထပ်ကြိုးစားပါ၊ response ပေးထားသော Retry-After သို့မဟုတ် rate-limit header များကို လိုက်နာပါ၊ retry count ကို ကန့်သတ်ထားပါ။ |
| A request seems to have succeeded twice | write operation များတွင် idempotency key သုံးပါ၊ ထို့ဖြင့် (retry သို့မဟုတ် နှစ်ချက်နှိပ်မိခြင်းကြောင့်) ဖြစ်လာသော duplicate စစ်စစ်ကို server က နှစ်ကြိမ်လုပ်မည့်အစား ဘေးကင်းစွာ လျစ်လျူရှုသည်။ |
| A webhook endpoint is receiving requests you're not sure are genuine | payload ကို မယုံကြည်မီ၊ မလုပ်ဆောင်မီ shared secret ဖြင့် webhook signature (HMAC) ကို အရင်စစ်ဆေးပါ။ |
| The same webhook event arrived twice | ဤအရာကို bug အဖြစ်မဟုတ်ဘဲ provider ၏ ပုံမှန်အပြုအမူအဖြစ် သဘောထားပါ — process ထားပြီးသား event ID များကို သိမ်းထားပြီး ကိုင်တွယ်ပြီးသားကို ကျော်ပါ။ |
| A third-party response is missing an expected field | data ကို မသုံးမီ response validation ထည့်ပါ၊ undefined ကို app ထဲသို့ တိတ်တဆိတ် စီးဝင်ခွင့်ပေးမည့်အစား ရှင်းလင်းသော internal error ဖြင့် fail လုပ်ပါ။ |
| You're not sure whether to use the SDK or raw API | သင့် language အတွက် official SDK ရှိလျှင် ၎င်းကို ဦးစားပေးပါ — auth header၊ retry၊ pagination များကို မှန်ကန်စွာ ကိုင်တွယ်ပြီးသားဖြစ်သည်၊ SDK မလွှမ်းခြုံသည့် အပိုင်းများအတွက်သာ raw call သုံးပါ။ |
| You need to test more than the happy path | 200 case တစ်ခုတည်းမက status အစစ်အမှန် (401၊ 403၊ 404၊ 429၊ 500) တစ်ခုစီအတွက် mock သုံးပြီး test case ရေးပါ — ပြောင်းလဲမှုတိုင်းတွင် run ရန် automate လုပ်ပါ။ |
| You're integrating an unfamiliar API for the first time | integration code မရေးမီ မှတ်တမ်း checklist ကို အရင်run ပါ (base URL၊ auth၊ endpoint၊ params၊ headers၊ body၊ response၊ errors၊ rate limit)။ |
| A secret credential might have leaked | credential ကို provider dashboard မှတစ်ဆင့် ချက်ချင်း rotate လုပ်ပါ (ပယ်ဖျက်ပြီး အသစ်ထုတ်ပါ) — code ထဲမှ ဖယ်ရှားရုံနှင့် မလုံလောက်ပါ၊ ဟောင်းတန်ဖိုးမှာ ပေါက်ကြားပြီးသား ဖြစ်နေသောကြောင့်ဖြစ်သည်။ |
| Deciding whether an API call should happen from the frontend or backend | call တစ်ခုတွင် secret credential လိုအပ်လျှင် backend proxy မှတစ်ဆင့် ပို့ပါ — မည်သူမဆို ဖတ်နိုင်သော frontend code ထဲတွင် secret key ထည့်ခြင်း မပြုလုပ်ပါနှင့်။ |
| An integration that worked yesterday broke today | မိမိ code ကို ချက်ချင်း အပြစ်တင်မည့်အစား version ပြောင်းလဲမှု သို့မဟုတ် deprecation notice ရှိမရှိ provider ၏ changelog ကို အရင်စစ်ပါ။ |