২৮ ফেব, ২০২৫·7 মিনিট পড়তে

স্পষ্ট, ব্যবহারকারী-বান্ধব বার্তার জন্য API ত্রুটি চুক্তির প্যাটার্ন

স্থিতিশীল কোড, লোকালাইজড বার্তা, এবং UI-বন্ধুবৰ্ধক হিন্ট সহ একটি API ত্রুটি চুক্তি ডিজাইন করুন — যা সাপোর্টের কাজ কমায় এবং ব্যবহারকারীদের দ্রুত পুনরুদ্ধার করতে সাহায্য করে।

স্পষ্ট, ব্যবহারকারী-বান্ধব বার্তার জন্য API ত্রুটি চুক্তির প্যাটার্ন

অস্পষ্ট API ত্রুটি কেন বাস্তব ব্যবহার সমস্যার সৃষ্টি করে

একটি অস্পষ্ট API ত্রুটি শুধু প্রযুক্তিগত ঝামেলা নয়। এটি পণ্যের মধ্যে একটি ভাঙা মুহূর্ত যখন কেউ আটকে যায়, ঠিক কী করতে হবে বলে ধরে নেয় এবং প্রায়ই ছেড়ে দেয়। সেই একক “কিছু ভুল হয়েছে” বার্তাটাই বেশি সাপোর্ট টিকিট, ইউজার চর্ন এবং এমন বাগ তৈরি করে যা কখনো পুরোপুরি মিটে না।

সাধারণ একটি দৃশ্য এই রকম: একজন ব্যবহারকারী একটি ফর্ম সেভ করার চেষ্টা করে, UI-তে একটি সাধারণ টোস্ট দেখায়, আর ব্যাকএন্ডের লগে থাকার আসল কারণ দেখা যায় ("unique constraint violation on email")। ব্যবহারকারী জানে না কী পরিবর্তন করবে। সাপোর্ট সাহায্য করতে পারে না কারণ লোগে অনুসন্ধানের জন্য নির্ভরযোগ্য কোনো কোড নেই। একই সমস্যা বিভিন্ন স্ক্রিনশট ও ভাষায় রিপোর্ট হয় আর গ্রুপ করার পরিষ্কার উপায় থাকে না।

ডেভেলপার ডিটেইল এবং ব্যবহারকারীর চাহিদা এক নয়। ইঞ্জিনিয়াররা চান সঠিক ব্যর্থতা প্রসঙ্গ (কোন ফিল্ড, কোন সার্ভিস, কোন টাইমআউট) — আর ব্যবহারকারী চান পরবর্তী স্পষ্ট পদক্ষেপ: “এই ইমেইল ইতিমধ্যে ব্যবহৃত হচ্ছে। সাইন ইন করুন অথবা অন্য ইমেইল ব্যবহার করুন।” দুইটা একসঙ্গে মিশালে সাধারণত হয় বা-তথ্য ফাঁস (ইন্টারনাল লিক) বা ব্যবহারহীন বার্তা (সবকিছু লুকানো)।

এখানেই API ত্রুটি চুক্তির প্রয়োজন পড়ে। উদ্দেশ্য বেশি ত্রুটি তৈরি করা নয়; বরং এক রকম কাঠামো যাতে:

  • ক্লায়েন্টগুলো বিভিন্ন এন্ডপয়েন্ট জুড়ে নির্ভরযোগ্যভাবে ব্যর্থতা ব্যাখ্যা করতে পারে\n- ব্যবহারকারীরা নিরাপদ, সাধারণ ভাষায় এমন বার্তা পায় যা তাদের পুনরুদ্ধারে সাহায্য করে\n- সাপোর্ট ও QA নির্দিষ্ট সমস্যাকে স্থায়ী কোড দিয়ে শনাক্ত করতে পারে\n- ইঞ্জিনিয়াররা ডায়াগনস্টিক পায়, কিন্তু সংবেদনশীল ডিটেইল প্রকাশ হয় না

কনসিস্টেন্সিই মূল। যদি এক এন্ডপয়েন্ট error: "Invalid" রিটার্ন করে আর অন্যটি message: "Bad request" দেয়, UI ব্যবহারকারীদের গাইড করতে পারে না এবং দলও নির্ণয় ও পরিমাপ করতে পারে না। একটি স্পষ্ট চুক্তি ত্রুটিকে পূর্বানুমেয়, অনুসন্ধানযোগ্য এবং ফিক্স করা সহজ করে, এমনকি আন্ডারলাইন কারণ বদলালেও।

বাস্তবে কনসিস্টেন্ট ত্রুটি চুক্তি মানে কী

API ত্রুটি চুক্তি একটি অঙ্গীকার: কিছু ভুল হলে আপনার API পরিচিত গাঠন ও পূর্বানুমেয় ফিল্ড ও কোড সহ প্রতিক্রিয়া দেবে, কোন এন্ডপয়েন্ট ব্যর্থেই হোক না কেন।

এটি ডিবাগিং ডাম্প নয়, এবং লগের বদলি নয়। চুক্তি হচ্ছে যা ক্লায়েন্ট অ্যাপ নিরাপদে নির্ভর করতে পারে। লগে রাখুন স্ট্যাক ট্রেস, SQL ডিটেইলস এবং সংবেদনশীল তথ্য।

প্রায়োগিকভাবে, একটি শক্ত চুক্তি কয়েকটা জিনিস স্থিতিশীল রাখে: রেসপন্স শেইপ (৪xx ও ৫xx উভয়ের জন্যই), মেশিন-পঠিত স্থায়ী ত্রুটি কোড এবং নিরাপদ ব্যবহারকারী-মুখী বার্তা। এটা সাপোর্টকে সাহায্য করে একটি request/trace নির্দেশক দিয়ে এবং সহজ UI হিন্টও রাখতে পারে, যেমন রিট্রাই করা উচিত কি না বা কোন ফিল্ড ঠিক করতে হবে।

কনসিস্টেন্সি তখনই কাজ করে যখন আপনি ঠিক করেন কোথায় বাধ্যবাধকতা আরোপ করবেন। টিমগুলো সাধারণত এক জায়গা থেকে শুরু করে পরে বাড়ায়: একটি API গেটওয়ে যা ত্রুটি নরমালাইজ করে, মিডলওয়্যার যা অনকট ঘাটতি র‍্যাপ করে, একটি শেয়ার্ড লাইব্রেরি যা একই ত্রুটি অবজেক্ট তৈরি করে, বা সার্ভিস স্তরের এক্সেপশন হ্যান্ডলার।

প্রধান প্রত্যাশা সহজ: প্রতিটি এন্ডপয়েন্ট বা সাফল্যের শেইপ রিটার্ন করবে, বা প্রতিটি ব্যর্থতার জন্য ত্রুটি চুক্তি। এতে ভ্যালিডেশন ত্রুটি, অথরাইজেশন ব্যর্থতা, রেট লিমিট, টাইমআউট, এবং আপস্ট্রিম আউটেজ সবই অন্তর্ভুক্ত।

একটি সহজ ত্রুটি রেসপন্স শেইপ যা বাড়ে

একটি ভালো API ত্রুটি চুক্তি ছোট, পূর্বানুমেয় এবং মানুষ ও সফটওয়্যার উভয়ের জন্যই ব্যবহারযোগ্য থাকে। যখন ক্লায়েন্ট সবসময় একই ফিল্ডগুলো খুঁজে পায়, সাপোর্ট আন্দাজ করা বন্ধ করে এবং UI পরিষ্কার সহায়তা দেয়।

নিচে এমন একটি মিনিমাল JSON শেইপ আছে যা বেশিরভাগ প্রোডাক্টে কাজ করে (এবং আরও এন্ডপয়েন্ট বাড়ালে স্কেল করে):

{
  "status": 400,
  "code": "AUTH.INVALID_EMAIL",
  "message": "Enter a valid email address.",
  "details": {
    "fields": {
      "email": "invalid_email"
    },
    "action": "fix_input",
    "retryable": false
  },
  "trace_id": "01HZYX8K9Q2..."
}

চুক্তি স্থিতিশীল রাখতে প্রতিটি অংশকে আলাদা অঙ্গীকার হিসেবে বিবেচনা করুন:

  • status HTTP আচরণ ও বিস্তৃত ক্যাটাগরির জন্য।\n- code হল স্থায়ী, মেশিন-পঠিত আইডেন্টিফায়ার (আপনার API ত্রুটি চুক্তির মূল)।\n- message নিরাপদ UI টেক্সট (এবং ভবিষ্যতে লোকালাইজ করা যাবে)।\n- details স্ট্রাকচার্ড হিন্ট রাখে: ফিল্ড-লেভেল সমস্যা, পরবর্তী করণীয়, এবং রিট্রাই যুক্তি।\n- trace_id সাপোর্টকে নির্দিষ্ট সার্ভার-সাইড ব্যর্থতা খুঁজে পেতে সাহায্য করে, কিন্তু ইন্টারনাল ডিটেইল ফাঁস করে না।

ব্যবহারকারী-মুখী কন্টেন্ট আলাদা রাখুন এবং অভ্যন্তরীণ ডিবাগিং তথ্য আলাদা রাখুন। যদি অতিরিক্ত ডায়াগনস্টিক দরকার হয়, সেগুলো সার্ভারে লগ রাখুন এবং trace_id দ্বারা কী করে মিলিয়ে দেখুন (রেসপন্সে নয়)। এতে সংবেদনশীল ডেটা ফাঁস হওয়া রোধ হয় কিন্তু সমস্যা তদন্ত করা সহজ থাকে।

ফিল্ড ত্রুটির জন্য, details.fields একটি সহজ প্যাটার্ন: কীগুলো ইনপুট নাম মিলে, মানগুলো সংক্ষিপ্ত কারণ ধরে রাখে যেমন invalid_email বা too_short। গাইডেন্স শুধুমাত্র তখনই যোগ করুন যখন তা সহায়ক হয়। টাইমআউটের জন্য action: "retry_later" যথেষ্ট হতে পারে। সাময়িক আউটেজের জন্য retryable: true ক্লায়েন্টকে রিট্রাই বাটন দেখাতে সাহায্য করে।

একটা নোট: কিছু টিম error অবজেক্টে সবকিছু র‍্যাপ করে (যেমন { "error": { ... } }), আর অন্যান্যেরা টপ-লেভেলে ফিল্ড রাখে। কোন পদ্ধতিই কাজ করতে পারে — গুরুত্বপূর্ণ হচ্ছে একটি এনভেলপ বেছে নেওয়া এবং প্রতিটি জায়গায় একই রাখা।

স্থায়ী ত্রুটি কোড: এমন প্যাটার্ন যা ক্লায়েন্ট ভাঙে না

স্থিতিশীল ত্রুটি কোড API ত্রুটি চুক্তির মেরুদন্ড। এগুলো অ্যাপ, ড্যাশবোর্ড এবং সাপোর্ট টিমকে একটি সমস্যা চিনতে দেয় এমনকি আপনি ওয়ার্ডিং বদলালেও বা ফিল্ড বাড়ালেও।

একটি ব্যবহারিক নামকরণ কনভেনশন হলো:

DOMAIN.ACTION.REASON

উদাহরণ: AUTH.LOGIN.INVALID_PASSWORD, BILLING.PAYMENT.CARD_DECLINED, PROFILE.UPDATE.EMAIL_TAKEN। ডোমেইনগুলো ছোট ও পরিচিত রাখুন (AUTH, BILLING, FILES)। ক্রিয়াপদের মতো অ্যাকশন ব্যবহার করুন (CREATE, UPDATE, PAY)।

কোডগুলোকে এন্ডপয়েন্টের মতো আচরণ করুন: একবার পাবলিক হলে তাদের মান বদলানো উচিত নয়। ব্যবহারকারীর কাছে দেখানো টেক্সট সময়ের সাথে উন্নত হতে পারে (ভাষা, টোন), কিন্তু কোডটি অপরিবর্তিত রাখা উচিত যাতে ক্লায়েন্ট ভাঙ্গে না এবং অ্যানালিটিক্স পরিষ্কার থাকে।

এছাড়া সিদ্ধান্ত নিন কোন কোড পাবলিক এবং কোনটা অভ্যন্তরীণ। সাধারণ নিয়ম: পাবলিক কোডগুলো UI-তে দেখানো নিরাপদ, স্থিতিশীল, ডকুমেন্টেড এবং UI দ্বারা ব্যবহারযোগ্য। অভ্যন্তরীণ কোড লগে রাখুন (ডাটাবেস নাম, ভেন্ডর ডিটেইলস, স্ট্যাক ইনফ)। একটি পাবলিক কোড বহু অভ্যন্তরীণ কারণকে মানতে পারে, বিশেষত যখন একটি ডিপেন্ডেন্সি বিভিন্নভাবে ব্যর্থ হতে পারে।

ডিপ্রেকেশন তখনই ভালো হয় যখন তা ভেজিল না হয়। যদি আপনাকে কোড প্রতিস্থাপন করতে হয়, তা চুপচাপ একটি নতুন মানে পুনরায় ব্যবহার করবেন না। একটি নতুন কোড পরিচয় করান এবং পুরানোটা ডিপ্রিকেট করা হিসেবে চিহ্নিত করুন। ক্লায়েন্টদের জন্য ওভারল্যাপ উইন্ডো দিন যেখানে দুদিকের কোডই দেখানো যেতে পারে। যদি একটি ফিল্ড deprecated_by দেয়, সেটিতে নতুন কোড দেখান (কোনও URL নয়)।

উদাহরণস্বরূপ, BILLING.PAYMENT.CARD_DECLINED বজায় রাখুন এমনকি আপনি UI কপি উন্নত করলে ও এটিকে দুইটি আলাদা গাইডে ভাগ করলেও — কোড স্থিতিশীল থাকলে অনুবর্তীতা অব্যাহত থাকে।

কনসিস্টেন্স হারিয়ে না দিয়ে লোকালাইজড বার্তা করা

সম্পূর্ণ অ্যাপ ওয়ার্কফ্লো তৈরি করুন
প্রতিটি ইন্টিগ্রেশন হাতে কোড না করে authentication, পেমেন্ট ও মেসেজিং মডিউল যোগ করুন
শুরু করুন

লোকালাইজেশন জটিল হয় যখন API পূর্ণ বাক্য রিটার্ন করে এবং ক্লায়েন্ট সেগুলোকে লজিক হিসেবে ব্যবহার করে। ভালো পদ্ধতি হলো চুক্তিটিকে স্থিতিশীল রাখা এবং "লাস্ট-মাইল" টেক্সট অনুবাদ করা ক্লায়েন্টে বা একক উৎসে করা। এতে একই ত্রুটি একই ভাষায় ও ডিভাইসে একই অর্থ রাখবে।

প্রথমে সিদ্ধান্ত নিন অনুবাদ কোথায় থাকবে। যদি আপনার ওয়েব, মোবাইল ও সাপোর্ট টুলে একক ট্রুথ দরকার হয়, সার্ভার-সাইড মেসেজ সহায়তা করতে পারে। যদি UI-তে টোন ও লেআউট নিয়ন্ত্রণ জরুরি, ক্লায়েন্ট-সাইড অনুবাদ সুবিধাজনক। অনেক টিম হাইব্রিড ব্যবহার করে: API একটি স্থিতিশীল কোড, message_key এবং পরামিটার রিটার্ন করে, আর ক্লায়েন্ট উপযুক্ত প্রদর্শনযোগ্য টেক্সট বেছে নেয়।

API ত্রুটি চুক্তির জন্য, মেসেজ কীগুলো সাধারণত হার্ডকোডেড বাক্যের চেয়ে নিরাপদ। API কিছুটা দেয় যেমন message_key: "auth.too_many_attempts" এবং params: {"retry_after_seconds": 300}। UI এটিকে অনুবাদ ও ফরম্যাট করে সরবরাহ করে।

প্লুরালাইজেশন এবং ফ্যালব্যাক গুরুত্বপূর্ণ। প্রতিটি লোকেলে প্লুরাল রুল সমর্থন করে এমন i18n সেটআপ ব্যবহার করুন। একটি ফ্যালব্যাক চেইন নির্ধারণ করুন (যেমন: fr-CA -> fr -> en) যাতে অনুপস্থিত স্ট্রিং খালি স্ক্রিন না করে।

একটি ভাল গাইডলাইন: অনুবাদকৃত টেক্সটকে কঠোরভাবে ব্যবহারকারী-মুখী হিসেবে ধরুন। স্ট্যাক ট্রেস, ইন্টারনাল আইডি বা কাঁচা ব্যর্থতার কারণ লোকালাইজড স্ট্রিংয়ে রাখবেন না। সংবেদনশীল ডিটেইল লগে রাখুন এবং ব্যবহারকারীর জন্য নিরাপদ ও কার্যকরী টেক্সট দিন।

ব্যাকএন্ড ব্যর্থতাকে UI হিন্টে পরিণত করা

আপনার API যেকোনো জায়গায় ডিপ্লয় করুন
AppMaster Cloud বা আপনার নিজস্ব AWS, Azure বা Google Cloud পরিবেশে ডিপ্লয় করুন
অ্যাপ তৈরি করুন

বহু ব্যাকএন্ড ত্রুটি ইঞ্জিনিয়ারের জন্য দরকারী, কিন্তু প্রায়ই সেগুলো স্ক্রিনে এসে পড়ে শুধু "কিছু ভুল হয়েছে" আকারে। একটি ভালো ত্রুটি চুক্তি ব্যর্থতাকে স্পষ্ট পরবর্তী ধাপে পরিণত করে, সংবেদনশীল ডিটেইল ফাঁস না করে।

সহজভাবে ব্যর্থতাগুলোকে তিনটি ব্যবহারকারি ক্রিয়ার মধ্যে ম্যাপ করুন: fix input, retry, বা contact support। এতে UI ওয়েব ও মোবাইলে সঙ্গতিবদ্ধ থাকে এমনকি ব্যাকএন্ডে বিভিন্ন ব্যর্থতার ভাণ্ডার থাকলেও।

  • Fix input: ভ্যালিডেশন ব্যর্থ, ফরম্যাট ভুল, প্রয়োজনীয় ফিল্ড অনুপস্থিত।\n- Retry: টাইমআউট, সাময়িক আপস্ট্রিম সমস্যা, রেট লিমিট।\n- Contact support: অনুমতি সমস্যা, ব্যবহারকারী মীমাংসা করতে না পারা কনফ্লিক্ট, অনাকাঙ্ক্ষিত অভ্যন্তরীণ ত্রুটি।

ফিল্ড হিন্টগুলি লম্বা বার্তার চেয়ে বেশি কার্যকর। যখন ব্যাকএন্ড জানে কোন ইনপুট ব্যর্থ হয়েছে, একটি মেশিন-পঠিত পয়েন্টার (যেমন email বা card_number) রিটার্ন করুন এবং একটি সংক্ষিপ্ত কারণ দিন যা UI ইনলাইন দেখাতে পারে। যদি একাধিক ফিল্ড ভুল থাকে, সবগুলো রিটার্ন করুন যাতে ব্যবহারকারী একবারে সব ঠিক করতে পারেন।

UI প্যাটার্নও পরিস্থিতির সাথে মিলিয়ে রাখুন। সাময়িক রিট্রাইয়ের জন্য টোস্ট ঠিক আছে; ইনপুট ত্রুটি ইনলাইন দেখান; অ্যাকাউন্ট বা পেমেন্ট ব্লকারগুলোর জন্য ব্লকিং ডায়ালগ দরকার।

একটি ধারাবাহিক ট্রাবলশুটিং কনটেক্সট রাখুন: trace_id, সময়বিন্দু যদি থাকে, এবং পরবর্তী সুপারিশ যেমন রিট্রাই ডিলে। এতে পেমেন্ট প্রোভাইডার টাইমআউট দেখালে UI বলবে "পেমেন্ট সার্ভিস ধীর। অনুগ্রহ করে আবার চেষ্টা করুন" এবং একটি রিট্রাই বাটন দেখাবে, আর সাপোর্ট একই trace_id দিয়ে সার্ভার-সাইড ব্যর্থতা যাচাই করতে পারবে।

ধাপে ধাপে: চুক্তি ইন্ড-টু-ইন্ড রোলআউট করা

এটি ছোট একটি প্রোডাক্ট পরিবর্তন মনে করে ইমপ্লিমেন্ট করুন, রেফ্যাক্টর নয়। ইঙ্ক্রিমেন্টাল রাখুন, এবং সাপোর্ট ও UI টিমদের আগে থেকে জড়িত করুন।

রোলআউট সিকোয়েন্স যা দ্রুত ব্যবহারকারী-মুখী বার্তা উন্নত করে কোন ক্লায়েন্ট ভাঙবে না:

  1. ইনভেন্টরি নিন (ডোমেইন অনুযায়ী গ্রুপ করুন)। লগ থেকে আসল ত্রুটি রেসপন্স এক্সপোর্ট করুন এবং auth, signup, billing, file upload, permissions ইত্যাদি বাটকে ভাগ করুন। রিপিট, অস্পষ্ট বার্তা এবং একই ব্যর্থতার বিভিন্ন শেইপ খুঁজুন।\n2. স্কিমা সংজ্ঞায়িত করুন এবং উদাহরণ শেয়ার করুন। রেসপন্স শেইপ, বাধ্যতামূলক ফিল্ড এবং ডোমেইনভিত্তিক উদাহরণ ডকুমেন্ট করুন। স্থায়ী কোড নাম, লোকালাইজেশনের জন্য একটি message key এবং UI-এর জন্য অপশনাল হিন্ট সন্নিবেশ করুন।\n3. একটি কেন্দ্রীয় ত্রুটি ম্যাপার ইমপ্লিমেন্ট করুন। ফরম্যাটিং এক জাগায় রাখুন যাতে প্রতিটি এন্ডপয়েন্ট একই কাঠামো রিটার্ন করে। জেনারেটেড ব্যাকএন্ড বা কোনো-নো-কোড ব্যাকএন্ডে এটি সাধারণত একটি শেয়ার্ড "map error to response" ধাপে হয় যা সব এন্ডপয়েন্ট বা বিজনেস প্রসেস কল করে।\n4. UI আপডেট করুন যাতে কোডগুলি ইন্টারপ্রেট করে এবং হিন্ট দেখায়। UI-কে টেক্সট নয়, কোডের ওপর নির্ভর করতে শেখান — কোন ফিল্ড হাইলাইট করতে হবে, রিট্রাই দেখাতে হবে, বা সাপোর্টে পাঠাতে হবে।\n5. লগিং যোগ করুন ও trace_id দিন যাতে সাপোর্ট সেটা চাইতে পারে। প্রতিটি রিকোয়েস্টে trace_id জেনারেট করুন, সার্ভারে কাঁচা ব্যর্থতার ডিটেইল লগ করুন, এবং রেসপন্সে trace_id রিটার্ন করুন যাতে ব্যবহারকারী কপি করে দিতে পারে।

প্রথম পাসের পরে, চুক্তিটি স্থিতিশীল রাখার জন্য কয়েকটি হালকা ওজনের আর্টিফ্যাক্ট রাখুন: প্রতিটি ডোমেইনের জন্য ত্রুটি কোডের শেয়ার্ড ক্যাটালগ, লোকালাইজেশনের ফাইল, কোড -> UI হিন্ট মানচিত্র, এবং একটি সাপোর্ট প্লেবুক যা শুরু হয় "আমাদের trace_id দিন" দিয়ে।

লিগ্যাসি ক্লায়েন্ট থাকলে পুরনো ফিল্ডগুলি সংক্ষিপ্ত অপসারণ উইন্ডো রাখুন, কিন্তু নতুন অনার্কিত শেইপ তৈরি করা বন্ধ করুন।

সাধারণ ভুল যা ত্রুটিকে সাপোর্ট করা কঠিন করে তোলে

স্কিমা থেকে বাস্তব API তৈরি করুন
আপনার ডেটা মডেল করুন এবং এমন একটি ব্যাকএন্ড জেনারেট করুন যা পূর্বানুমেয় ত্রুটি আকৃতি ফেরত দেয়
প্রকল্প তৈরি করুন

অধিকাংশ সাপোর্ট-যন্ত্রণা আসে অস্পষ্টতাই। যখন API ত্রুটি চুক্তি অসংগত থাকে, প্রত্যেক টিম তাদের নিজস্ব ব্যাখ্যা বানায় এবং ব্যবহারকারীরা এমন বার্তা পেয়ে আটকে যায় যা তারা কার্যকরভাবে ব্যবহার করতে পারে না।

একটি সাধারণ ফাঁদ হলো HTTP স্ট্যাটাস কোডকে সম্পূর্ণ গল্প ধরে নেয়া। "400" বা "500" বলে প্রায় কিছুই ব্যবহারকারীকে পরবর্তী ধাপ সম্পর্কে বলে না। স্ট্যাটাস কোড ট্রান্সপোর্ট ও বিস্তৃত শ্রেণিবিভাগে সাহায্য করে, কিন্তু আপনাকে একটি স্থায়ী, অ্যাপ-লেভেল কোডের প্রয়োজন আছে যা সংস্করণ জুড়ে মান রাখে।

আরেকটি ভুল হলো একটি কোডের অর্থ সময়ের সাথে বদলানো। যদি PAYMENT_FAILED আগে মানে ছিল "কার্ড প্রত্যাখ্যাত" এবং পরে মানে হয় "Stripe ডাউন", তাহলে UI ও ডক ভুল তথ্য দেখাবে। সাপোর্ট তখন পাবেন টিকেট যেমন "আমি তিনটি কার্ড চেষ্টা করেছি, তবুও ব্যর্থ" যখন আসল সমস্যা আউটেজ।

র' এক্সসেপশন টেক্সট (বা স্ট্যাক ট্রেস) সরাসরি রিটার্ন করাটা দ্রুতtempting, কিন্তু ব্যবহারকারীর কাছে সহায়ক নয় এবং সংবেদনশীল তথ্য ফাঁস করতে পারে। র বা র ডিটেইলস রাখুন লগে, রেসপন্সে নয়।

কিছু ধারাবাহিকভাবে গোলমাল করা প্যাটার্ন:

  • UNKNOWN_ERROR মতো ক্যাচ-অল কোড অতিরিক্ত ব্যবহারে কোনো নির্দেশ দেয় না।\n- একটি পরিষ্কার ট্যাক্সোনমি ছাড়া অনেক কোড তৈরি করলে ড্যাশবোর্ড ও প্লেবুক বজায় রাখা কঠিন হয়।\n- ব্যবহারকারী-ফেসিং টেক্সট ও ডেভ-ডায়াগনস্টিক একই ফিল্ডে রাখলে লোকালাইজেশন ও UI হিন্ট ভঙ্গুর হয়।

একটি সহজ নিয়ম কাজ করে: প্রত্যেক ব্যবহারকারী সিদ্ধান্তের জন্য একটি স্থায়ী কোড। ব্যবহারকারী ইনপুট বদলে সমস্যার সমাধান করতে পারলে নির্দিষ্ট কোড ও স্পষ্ট হিন্ট দিন। যদি তারা কিছুই করতে না পারে (যেমন প্রোভাইডার আউটেজ), তাহলে কোড স্থিতিশীল রাখুন এবং নিরাপদ বার্তা সহ "পরে আবার চেষ্টা করুন" ও একটি সম্পর্কিত ID রিটার্ন করুন।

দ্রুত প্রি-রিলিজ চেকলিস্ট

শিপ করার আগে ত্রুটিকে একটি প্রোডাক্ট ফিচার হিসেবে দেখুন। কিছু ব্যর্থ হলে ব্যবহারকারী জানতে পারবে পরবর্তী করণীয়, সাপোর্ট একই ঘটনাটি খুঁজে পাবে, আর ব্যাকএন্ড বদলালেও ক্লায়েন্ট ভাঙ্গবে না।

  • সব জায়গায় একই শেইপ: প্রতিটি এন্ডপয়েন্ট (auth, webhooks, file uploads সহ) এক সম্মিলিত ত্রুটি এনভেলপ রিটার্ন করবে।\n- স্থিতিশীল, দায়িত্বশীল কোড: প্রতিটি কোডের স্পষ্ট মালিক (Payments, Auth, Billing) থাকবে। একই কোড দিয়ে ভিন্ন অর্থ ব্যবহার করবেন না।\n- নিরাপদ, লোকালাইজেবল মেসেজ: ব্যবহারকারী-ফেসিং টেক্সট সংক্ষিপ্ত রাখুন এবং কখনই সিকিউরিটি-রলি তথ্য না দিন (টোকেন, সম্পূর্ণ কার্ড ডেটা, কাঁচা SQL, স্ট্যাক ট্রেস)।\n- স্পষ্ট UI পরবর্তী পদক্ষেপ: প্রধান ত্রুটি টাইপগুলোর জন্য UI একটি সহজ পরবর্তী পদক্ষেপ দেখায় (আবার চেষ্টা করুন, ফিল্ড আপডেট করুন, অন্য পেমেন্ট পদ্ধতি ব্যবহার করুন, সাপোর্টে যোগাযোগ করুন)।\n- সাপোর্টের জন্য ট্রেসএবিলিটি: প্রতিটি ত্রুটি রেসপন্সে trace_id থাকবে এবং আপনার লগিং/মনিটরিং দ্রুত পুরো গল্প খুঁজে পাবে।

কিছু বাস্তব ফ্লো এন্ড-টু-এন্ড টেস্ট করুন: একটি ইনভ্যালিড ইনপুট ফর্ম, মেয়াদোত্তীর্ণ সেশন, রেট লিমিট, এবং তৃতীয়-পক্ষ আউটেজ। যদি আপনি এক বাক্যে ব্যর্থতা ব্যাখ্যা করতে না পারেন এবং লগে নির্দিষ্ট trace_id দেখাতে না পারেন, তাহলে শিপের জন্য প্রস্তুত নন।

উদাহরণ: সাইনআপ ও পেমেন্ট ব্যর্থতা যাতে ব্যবহারকারী পুনরুদ্ধার করতে পারে

ত্রুটি কোড দ্রুত স্ট্যান্ডার্ড করুন
স্থিতিশীল ত্রুটি কোড তৈরি করুন এবং ভ্যালিডেশন ত্রুটিগুলো এক জায়গায় মোকাবিলা করুন
তৈরি শুরু করুন

একটি ভালো API ত্রুটি চুক্তি একই ব্যর্থতিকে তিনটি জায়গায় বোঝাপড়া যোগ্য রাখে: ওয়েব UI, মোবাইল অ্যাপ, এবং ব্যর্থ প্রচেষ্টার পরে স্বয়ংক্রিয় ইমেইল। এটি সাপোর্টকে পর্যাপ্ত ডিটেইল দেয় সাহায্য করতে, ব্যবহারকারীকে প্রতিটি স্ক্রিনে একই নির্দেশ দিবে।

সাইনআপ: ব্যবহারকারী ঠিক করতে পারে এমন ভ্যালিডেশন ত্রুটি

ব্যবহারকারী ইমেইল হিসেবে sam@ এন্ট্রি করে Sign up ট্যাপ করলে API একটি স্থিত কোড ও ফিল্ড-লেভেল হিন্ট রিটার্ন করবে, যাতে প্রতিটি ক্লায়েন্ট একই ইনপুট হাইলাইট করতে পারে।

{
  "error": {
    "code": "AUTH.EMAIL_INVALID",
    "message": "Enter a valid email address.",
    "i18n_key": "auth.email_invalid",
    "params": { "field": "email" },
    "ui": { "field": "email", "action": "focus" },
    "trace_id": "4f2c1d..."
  }
}

ওয়েবে আপনি ইমেইল বক্সের নিচে মেসেজ দেখাবেন। মোবাইল এ ফোকাস করে ছোট ব্যানার দেখাবেন। ইমেইলে বলা যেতে পারে: "আমরা আপনার অ্যাকাউন্ট তৈরি করতে পারিনি কারণ ইমেইল ঠিকমতো পূর্ণ করা হয়নি।" একই কোড, একই অর্থ।

পেমেন্ট: নিরাপদ ব্যাখ্যার সঙ্গে ব্যর্থতা

একটি কার্ড পেমেন্ট ব্যর্থ হলে ব্যবহারকারীকে গাইড করতে হবে, কিন্তু প্রসেসরের অভ্যন্তরীণ ডিটেইল প্রকাশ করা উচিত নয়। চুক্তি ব্যবহারকারীর দেখার অংশ ও সাপোর্টের যাচাইযোগ্য অংশ আলাদা রাখতে পারে।

{
  "error": {
    "code": "PAYMENT.DECLINED",
    "message": "Your payment was declined. Try another card or contact your bank.",
    "i18n_key": "payment.declined",
    "params": { "retry_after_sec": 0 },
    "ui": { "action": "show_payment_methods" },
    "trace_id": "b9a0e3..."
  }
}

সাপোর্ট trace_id চাইলে জানতে পারবে কোন স্থায়ী কোড রিটার্ন হয়েছে, ডিক্লাইন ফাইনাল না রিট্রাইযোগ্য কিনা, অ্যাকাউন্ট ও অ্যামাউন্ট কিসের ছিল ইত্যাদি — সব কিছু সার্ভার-লগ দেখে নির্ণয় করা যাবে।

এখানেই API ত্রুটি চুক্তির মূল্য আসে: ওয়েব, iOS/Android এবং ইমেইল ফ্লো কনসিস্টেন্ট থাকে এমনকি ব্যাকএন্ড প্রোভাইডার বা অভ্যন্তরীণ বিস্তারিত বদলালেও।

সময়ের সাথে আপনার ত্রুটি চুক্তি টেস্ট ও মনিটর করা

স্পষ্ট ত্রুটিসহ API তৈরি করুন
একটি একইরকম ত্রুটি প্রতিক্রিয়া ডিজাইন করুন এবং প্রত্যেক এন্ডপয়েন্টে পুনরায় ব্যবহার করুন
AppMaster চেষ্টা করুন

একটি API ত্রুটি চুক্তি শিপের সঙ্গে শেষ হয় না। এটি তখনই ঠিকঠাক চলে যখন একই ত্রুটি কোড ধারাবাহিকভাবে একই ব্যবহারকারী ক্রিয়ায় নিয়ে যায়, এমনকি মাস খানেকের রিফ্যাক্টর ও নতুন ফিচার এলেও।

বাইরের দিক থেকে ক্লায়েন্টের মত করে টেস্ট শুরু করুন। প্রতিটি ত্রুটি কোডের জন্য অন্তত একটি রিকোয়েস্ট লিখে তা ট্রিগার করুন এবং আপনি যেটার ওপর নির্ভর করেন তা assert করুন: HTTP status, code, localization key, এবং UI হিন্ট ফিল্ড (কোন ফর্ম ফিল্ড হাইলাইট হবে) ইত্যাদি।

একটি ছোট টেস্ট সেট বেশিরভাগ ঝুঁকি কভার করে:

  • প্রতিটি ত্রুটি কেসের পাশে একটি হ্যাপি-পাথ রিকোয়েস্ট (অ্যাক্সিডেন্টালি ওভার-ভ্যালিডেশন ধরতে)\n- প্রতিটি স্থায়ী কোডের জন্য একটি টেস্ট যাতে UI হিন্ট বা ফিল্ড ম্যাপিং চেক করে\n- একটি টেস্ট যাতে অজানা ব্যর্থতা একটি নিরাপদ জেনেরিক কোড রিটার্ন করে\n- একটি টেস্ট যাতে প্রতিটি সমর্থিত ভাষার জন্য লোকালাইজেশন কী আছে তা নিশ্চিত করে\n- একটি টেস্ট যাতে নিশ্চিত করে সংবেদনশীল ডিটেইলস ক্লায়েন্ট রেসপন্সে কখনো আসে না

মনিটরিং এমন রেগ্রেশন ধরতে সহায়তা করে যা টেস্ট মিস করে। সময়ের সাথে ত্রুটি কোডের গণনা ট্র্যাক করুন এবং আকস্মিক বৃদ্ধি হলে অ্যালার্ট দিন (যেমন, একটি পেমেন্ট কোড রিলিজ পর ডাবল হয়ে গেলে)। প্রোডাকশনে নতুন কোনো কোড দেখা গেলে সেও লক্ষ্য রাখুন — সম্ভবত কেউ চুক্তি বাইপাস করেছে।

প্রাথমিকভাবে সিদ্ধান্ত নিন কী অভ্যন্তরীণ থাকবে এবং কী ক্লায়েন্টকে দেওয়া হবে। একটি বাস্তবসম্মত বিভাজন: ক্লায়েন্ট পাবে স্থায়ী কোড, লোকালাইজেশন কী, ও একটি ব্যবহারকারী-অ্যাকশন হিন্ট; লগে থাকবে কাঁচা এক্সসেপশন, স্ট্যাক ট্রেস, রিকোয়েস্ট ID, এবং ডিপেন্ডেন্সি ব্যর্থতার ডিটেইলস।

মাসে একবার রিয়েল সাপোর্ট কনভারসেশন দেখে ত্রুটিগুলো পর্যালোচনা করুন। ভলিউম অনুযায়ী শীর্ষ পাঁচটি কোড নিন এবং প্রতিটির জন্য কয়েকটি টিকিট পড়ুন। যদি ব্যবহারকারীরা বারবার একই অনুরোধ করে, UI হিন্টে একটি ধাপ মিসিং আছে বা মেসেজ খুব অস্পষ্ট।

পরবর্তী ধাপ: প্যাটার্নটি আপনার প্রোডাক্ট ও ওয়ার্কফ্লোতে প্রয়োগ করা

যেখানে বিভ্রান্তি সবচেয়ে ব্যয়বহুল সেই জায়গা থেকে শুরু করুন: সাধারণত যে ধাপগুলোতে ড্রপঅফ বেশি (সাইনআপ, চেকআউট, ফাইল আপলোড) এবং যেসব ত্রুটি বেশি টিকিট তৈরি করে সেগুলো প্রথম স্ট্যান্ডার্ড করুন যাতে আপনি একটি স্প্রিন্টে প্রভাব দেখা শুরু করতে পারেন।

কিছু ব্যবহারিক টিপস:

  • টপ ১০ সাপোর্ট-চালিত ত্রুটির জন্য স্থায়ী কোড নির্ধারণ করে ডিফল্ট সেট করুন\n- প্রতিটি সারফেস (ওয়েব, মোবাইল, অ্যাডমিন) অনুযায়ী কোড -> UI হিন্ট -> পরবর্তী অ্যাকশন মানচিত্র নির্ধারণ করুন\n- নতুন এন্ডপয়েন্টের জন্য চুক্তিটিকে ডিফল্ট বানান এবং অনুপস্থিত ফিল্ডগুলোকে রিভিউ-ফেইল হিসেবে বিবেচনা করুন\n- একটি ছোট অভ্যন্তরীণ প্লেবুক রাখুন: প্রতিটি কোডের মানে, সাপোর্ট কী চাইবে, এবং কার দায়িত্ব মেরামত করা\n- কয়েকটি মেট্রিক ট্র্যাক করুন: কোড অনুযায়ী ত্রুটি হার, "UNKNOWN_ERROR" গণনা, এবং প্রতিটি কোডের টিকিট ভলিউম

যদি আপনি AppMaster প্ল্যাটফর্ম দিয়ে নির্মাণ করেন, তখন এটা আগেভাগে সংজ্ঞায়িত করা মূল্যবান: আপনার এন্ডপয়েন্টের জন্য একটি কনসিস্টেন্ট ত্রুটি শেইপ নির্ধারণ করুন, তারপর UI ম্যাপ করে ওয়েব ও মোবাইল স্ক্রিনে স্থায়ী কোডগুলোর জন্য একই অর্থ প্রদর্শন করুন।

একটি সহজ উদাহরণ: যদি সাপোর্ট বারবার "Payment failed" জবাব পায়, স্ট্যান্ডার্ডাইজ করে UI একটি কোডের জন্য "Card declined" দেখাবে এবং টিপস দেবে আরেকটি কার্ড চেষ্টা করুন, আর আরেক কোডের জন্য বলবে "Payment system temporarily unavailable" ও রিট্রাই বাটন দেখাবে। সাপোর্ট এখন কেবল trace_id চেয়ে পারে বুলিয়ে না গেস করে।

একটি পুনরাবৃত্তি ক্লিনআপ ক্যালেন্ডার রাখুন: অব্যবহৃত কোড অবসান করুন, অস্পষ্ট মেসেজ সরান, এবং যেখানে বাস্তব ভলিউম আছে সেখানে লোকালাইজেশন যোগ করুন। চুক্তি স্থিতিশীল থাকুক, পণ্য পরিবর্তিত হোক।

শুরু করা সহজ
কিছু আশ্চর্যজনকতৈরি করুন

বিনামূল্যের পরিকল্পনা সহ অ্যাপমাস্টারের সাথে পরীক্ষা করুন।
আপনি যখন প্রস্তুত হবেন তখন আপনি সঠিক সদস্যতা বেছে নিতে পারেন৷

এবার শুরু করা যাক