প্রথমবারের SaaS নির্মাতাদের জন্য পাবলিক API ডিজাইন: মৌলিক বিষয়গুলি
প্রথমবারের SaaS নির্মাতাদের জন্য বাস্তবসম্মত পাবলিক API ডিজাইন: ভার্সনিং, পেজিনেশন, রেট লিমিট, ডকস, এবং দ্রুত পাঠাতে পারে এমন একটি ছোট SDK বাছাই করুন।

সত্যিকারের সমস্যা: এমন একটি API প্রকাশ করা যা আপনি বজায় রাখতে পারবেন
একটি পাবলিক API মাত্র আপনার অ্যাপের একটি এন্ডপয়েন্ট নয়। এটি আপনার টিমের বাইরে মানুষদের প্রতি একটি প্রতিশ্রুতি যে চুক্তিটি কাজ করতেই থাকবে, এমনকি আপনি পণ্য বদলালেও।
কঠিন জিনিসটি হলো v1 লেখা নয়। বরং, তা স্থিতিশীল রাখা যখন আপনি বাগ ঠিক করছেন, ফিচার যোগ করছেন, এবং গ্রাহকরা আসলে কী চায় তা শিখছেন।
প্রাথমিক সিদ্ধান্তগুলো পরে সাপোর্ট টিকিট হিসেবে ফিরে আসে। যদি রেসপন্স আকৃতি অপ্রত্যাশিতভাবে বদলে যায়, নামকরণ অনিয়মিত হয়, বা ক্লায়েন্টরা বুঝতে না পারে অনুরোধ সফল হয়েছে কি না, আপনি ফ্রিকশন সৃষ্টি করেন। সেই ফ্রিকশন অবিশ্বাসে পরিণত হয়, আর অবিশ্বাস মানুষকে আপনার উপর নির্মাণ বন্ধ করতে বাধ্য করে।
গতিতাও গুরুত্বপূর্ণ। বেশিরভাগ প্রথমবারের SaaS নির্মাতাদের জরুরি কিছু দ্রুত পাঠাতে হয়, তারপর তা উন্নত করতে হয়। বিনিময়টি সরল: যদি আপনি নিয়ম ছাড়া দ্রুত পাঠান, বাস্তব ব্যবহারকারীরা এলে আপনি সেই সিদ্ধান্তগুলো উল্টাতে বেশি সময় ব্যয় করবেন।
v1-এর জন্য সাধারণত যথেষ্ট মানে হলো একটি ছোট এন্ডপয়েন্ট সেট যা বাস্তব ব্যবহারকারীর অ্যাকশনের সাথে মেলে, ধারাবাহিক নামকরণ এবং রেসপন্স শেপ, একটি স্পষ্ট পরিবর্তন কৌশল (এমনকি সেটা কেবল v1 বলেই কেন না), পূর্বানুমানযোগ্য পেজিনেশন এবং যুক্তিসংগত রেট লিমিট, এবং এমন ডকস যা ঠিক দেখায় আপনি কী পাঠাতে হবে এবং কী পেয়ে যাবেন।
একটি বাস্তব উদাহরণ: ভাবুন কোনো গ্রাহক একটি ইন্টিগ্রেশন বানিয়েছে যা রাতের বেলায় ইনভয়েস তৈরি করে। যদি আপনি পরে একটি ফিল্ডের নাম বদলে দেন, তারিখ ফরম্যাট পরিবর্তন করেন, বা নিশ্চুপভাবে আংশিক রেজাল্ট ফেরত দিতে শুরু করেন, তাদের কাজ ভোর ২টায় ব্যর্থ হয়ে যাবে। তারা আপনার API-কে দোষ দেবে, নিজের কোডকে নয়।
Koder.ai-এর মতো একটি চ্যাট-চালিত টুল দিয়ে তৈরি করলে অনেক এন্ডপয়েন্ট দ্রুত জেনারেট করা লোভজনক হবে। এটাই ঠিক, তবে পাবলিক সারফেস ছোট রাখুন। আপনি অভ্যন্তরীণ এন্ডপয়েন্টগুলো প্রাইভেট রাখতেও পারেন যখন পর্যন্ত আপনি শিখছেন কোনগুলো দীর্ঘমেয়াদী চুক্তির অংশ হওয়া উচিত।
একটি ছোট, পরিষ্কার API সারফেস দিয়ে শুরু করুন
ভাল পাবলিক API ডিজাইন শুরু হয় এমন একটি ছোট সেট নাম (নাউন/রিসোর্স) বেছে নিয়ে যা গ্রাহকরা আপনার পণ্যের সম্পর্কে কথায় ব্যবহার করে। রিসোর্স নামগুলো স্থিতিশীল রাখুন এমনকি আপনার অভ্যন্তরীণ ডাটাবেস বদলালেও। যখন আপনি ফিচার যোগ করবেন, মূল রিসোর্সের নাম পরিবর্তন করার চেয়ে নতুন ফিল্ড বা নতুন এন্ডপয়েন্ট যোগ করা পছন্দ করুন।
অনেক SaaS পণ্যের জন্য একটি বাস্তবসম্মত সূচনা সেট হলো: users, organizations, projects, এবং events। আপনি যদি একটি রিসোর্স এক বাক্যে ব্যাখ্যা করতে না পারেন, তাহলে সেটি সম্ভবত পাবলিক হওয়ার জন্য প্রস্তুত নয়।
HTTP ব্যবহারে বোরিং এবং পূর্বানুমানযোগ্য থাকুন:
- GET ডেটা পড়ে (কোন সাইড-এফেক্ট নয়)
- POST কিছু তৈরি করে (বা একটি অ্যাকশন শুরু করে)
- PATCH কয়েকটি ফিল্ড আপডেট করে
- DELETE কিছু মুছে বা অক্ষম করে
প্রথম দিনে অথ খুব ফ্যান্সি হতে হবে না। যদি আপনার API মূলত সার্ভার-টু-সার্ভার হয় (গ্রাহকরা তাদের ব্যাকএন্ড থেকে কল করে), API কী প্রায়ই যথেষ্ট। যদি গ্রাহকদের ব্যক্তিগত এন্ড-ইউজার হিসেবে কাজ করতে হয়, অথবা আপনি তৃতীয় পক্ষের ইন্টিগ্রেশন আশা করেন যেখানে ব্যবহারকারীরা অনুমতি দেয়, তাহলে সাধারণত OAuth ভালো ফিট। সিদ্ধান্তটি সাদামাটা ভাষায় লিখুন: কে কল করছে, এবং তারা কার ডেটা স্পর্শ করার অনুমতি পায়?
শুরুতেই প্রত্যাশা সেট করুন। কী সমর্থিত বনাম কোনটা বেস্ট-এফোর্ট পরিষ্কারভাবে বলুন। উদাহরণ: লিস্ট এন্ডপয়েন্টগুলো স্থিতিশীল এবং ব্যাকওয়ার্ড-কম্প্যাটিবল, কিন্তু সার্চ ফিল্টার বাড়তে পারে এবং সর্বজনীনভাবে সম্পূর্ণ না-ও হতে পারে। এটা সাপোর্ট টিকিট কমায় এবং আপনাকে উন্নত করার স্বাধীনতা দেয়।
Koder.ai-এর মতো ভিব-কোডিং প্ল্যাটফর্মে তৈরি করলে API-কে একটি প্রোডাক্ট চুক্তি হিসেবে বিবেচনা করুন: প্রথমে চুক্তিটা ছোট রাখুন, তারপর বাস্তব ব্যবহার অনুযায়ী বাড়ান, অনুমানের উপর নয়।
কোণঠাসা না করে ভার্সনিং শুরু করুন
ভার্সনিং মূলত প্রত্যাশার ব্যাপার। ক্লায়েন্টরা জানতে চায়: আমার ইন্টিগ্রেশন আগামী সপ্তাহে ভেঙে যাবে? আপনি উন্নতি করার জন্য জায়গা চান ভয়ের ছাড়া।
URL ভার্সনিং বনাম হেডার ভার্সনিং
হেডার-ভিত্তিক ভার্সনিং পরিষ্কার মনে হতে পারে, কিন্তু এটি লগ, ক্যাশ, এবং সাপোর্ট স্ক্রীনশট থেকে লুকিয়ে রাখা সহজ। URL ভার্সনিং সাধারণত সবচেয়ে সরল পছন্দ: /v1/...। যখন কোনো গ্রাহক ব্যর্থ অনুরোধ পাঠায়, আপনি তাত্ক্ষণিকভাবে ভার্সন দেখতে পারবেন। এটি v1 এবং v2 পাশাপাশি চালাতে সহজ করেও তোলে।
বাস্তবে কোনটা ব্রেকিং চেঞ্জ?
একটি চেঞ্জ ব্রেকিং যদি একটি ভাল-আচরণকারী ক্লায়েন্ট কোনো কোড বদল না করেই কাজ করা বন্ধ করতে পারে। সাধারণ উদাহরণগুলো:
- একটি ফিল্ডের নাম বদলানো (উদাহরণ:
customer_idথেকেcustomerId) - একটি ফিল্ড টাইপ (স্ট্রিং থেকে নম্বর) বা তার অর্থ পাল্টানো
- কোনো এন্ডপয়েন্ট বা রেসপন্স ফিল্ড অপসারণ করা যেগুলো ক্লায়েন্ট নির্ভর করে
- ভ্যালিডেশন নিয়ম কঠোর করা (আগে ঐচ্ছিক ছিল, এখন বাধ্যতামূলক)
- অথ বা ডিফল্ট পারমিশন বদলানো
একটি নিরাপদ পরিবর্তন হলো যা পুরোনো ক্লায়েন্টরা উপেক্ষা করতে পারে। একটি নতুন ঐচ্ছিক ফিল্ড যোগ করা সাধারণত নিরাপদ। উদাহরণস্বরূপ, GET /v1/subscriptions রেসপন্সে plan_name যোগ করলে ক্লায়েন্ট যারা কেবল status পড়ে, তারা ভেঙে যাবে না।
একটি ব্যবহারিক নিয়ম: একই মেজর ভার্সনের ভিতরে ফিল্ড পরিবর্তন বা পুনরায় ব্যবহার করা থেকে বিরত থাকুন। নতুন ফিল্ড যোগ করুন, পুরোনোগুলো রাখুন, এবং সম্পূর্ণ ভার্সন ডিপ্রিকেট করার সময়ই সেগুলো অবসর দিন।
আপনি অনুসরণ করতে পারবেন এমন একটি ডিপ্রেকশন নীতি
সরল রাখুন: ডিপ্রেকশন আগে ঘোষণা করুন, রেসপন্সে একটি স্পষ্ট ওয়ার্নিং মেসেজ দিন, এবং একটি শেষ তারিখ নির্ধারণ করুন। প্রথম API-এর জন্য 90 দিনের উইন্ডো বাস্তবসম্মত। সেই সময়ে v1 কাজ করে রাখুন, একটি সংক্ষিপ্ত মাইগ্রেশন নোট প্রকাশ করুন, এবং সাপোর্ট যাতে এক বাক্যে বলতে পারে: v1 এই তারিখ পর্যন্ত কাজ করবে; v2-তে কী বদলেছে।
আপনি Koder.ai-এর মতো প্ল্যাটফর্মে তৈরি করলে API ভার্সনকে স্ন্যাপশটের মতো বিবেচনা করুন: উন্নতি নতুন ভার্সনে পাঠান, পুরোনোটা স্থির রাখুন, এবং কেবল তখনই বন্ধ করুন যখন গ্রাহকদের মাইগ্রেশনের জন্য পর্যাপ্ত সময় দিয়েছেন।
পেজিনেশন প্যাটার্ন যা পূর্বানুমানযোগ্য থাকে
পেজিনেশনই এমন জায়গা যেখানে বিশ্বাস জয় বা হারানো হয়। যদি রেজাল্ট অনুরোধের মধ্যে ঝাঁপি-ঝাঁপি বদলে যায়, মানুষ আপনার API-র ওপর বিশ্বাস হারাবেন।
ডেটাসেট ছোট এবং ক্বেরি সহজ হলে page/limit ব্যবহার করুন এবং ব্যবহারকারীরা প্রায়ই পৃষ্ঠা 3 এর মতো সরাসরি যেতে চান। তালিকাগুলো বড় হলে, নতুন আইটেম ঘনঘন আসলে, অথবা ব্যবহারকারী অনেক সাজানো/ফিল্টার করে তখন কারসর-ভিত্তিক পেজিনেশন ব্যবহার করুন। কারসর-ভিত্তিক পেজিনেশন নতুন রেকর্ড যোগ হলেও ক্রমকে স্থিতিশীল রাখে।
কয়েকটি নিয়ম পেজিনেশনকে নির্ভরযোগ্য রাখে:
- সর্বদা একটি ডিফল্ট сорт নির্ধারণ করুন (উদাহরণ: created_at desc)।
- একটি টাই-ব্রেকার যোগ করুন (উদাহরণ: id) যাতে অর্ডার নির্ধারিত হয়।
- পেজিনেশনকে চুক্তির অংশ হিসেবে বিবেচনা করুন: পরে সোর্ট পরিবর্তন করা একটি ব্রেকিং চেঞ্জ।
- চালিয়ে যেতে ন্যূনতম প্রয়োজনীয় তথ্য রিটার্ন করুন: আইটেমগুলো প্লাস পরের কারসর (বা পরের পৃষ্ঠা)।
টোটালস জটিল। একটি total_count বড় টেবিলে ব্যয়সাপেক্ষ হতে পারে, বিশেষত ফিল্টারসহ। যদি আপনি সহজে প্রদান করতে পারেন, অন্তর্ভুক্ত করুন। না পারলে, এটি বাদ দিন বা একটি কুয়েরি ফ্ল্যাগের মাধ্যমে ঐচ্ছিক করুন।
নীচে সহজ অনুরোধ/রেসপন্স শেপ আছে।
// Page/limit
GET /v1/invoices?page=2\u0026limit=25\u0026sort=created_at_desc
{
"items": [{"id":"inv_1"},{"id":"inv_2"}],
"page": 2,
"limit": 25,
"total_count": 142
}
// Cursor-based
GET /v1/invoices?limit=25\u0026cursor=eyJjcmVhdGVkX2F0IjoiMjAyNi0wMS0wOVQxMDozMDowMFoiLCJpZCI6Imludl8xMDAifQ==
{
"items": [{"id":"inv_101"},{"id":"inv_102"}],
"next_cursor": "eyJjcmVhdGVkX2F0IjoiMjAyNi0wMS0wOVQxMDoyNTowMFoiLCJpZCI6Imludl8xMjUifQ=="
}
রেট লিমিট এবং বান্ধব রিট্রাই প্যাটার্ন
রেট লিমিট কঠোর হওয়ার চেয়ে অনলাইনে থাকা রক্ষা করাই বেশি গুরুত্বপূর্ণ। এগুলো আপনার অ্যাপকে ট্রাফিক স্পাইক থেকে, আপনার ডাটাবেসকে ব্যয়বহুল কুয়েরি থেকে, এবং আপনার ওয়ালেটকে অপ্রত্যাশিত অবকাঠামো বিল থেকে রক্ষা করে। একটি লিমিটও একটি চুক্তি: ক্লায়েন্টরা জানে স্বাভাবিক ব্যবহার কী রকম।
সরলভাবে শুরু করুন এবং পরে টিউন করুন। সাধারণ ব্যবহার কভার করে এমন, স্বল্প বরস্টের জায়গা রেখে এমনটি বেছে নিন, তারপর বাস্তব ট্র্যাফিক দেখুন। যদি আপনার কোনো এন্ডপয়েন্ট অনেক ভারী হয় (যেমন সার্চ বা এক্সপোর্ট), সেটিকে কঠোরতর লিমিট দিন অথবা আলাদা কস্ট রুল দিন, প্রতিটি অনুরোধকে শাস্তি না দেওয়ার বদলে।
যখন আপনি লিমিট প্রয়োগ করেন, ক্লায়েন্টদের সঠিক কাজ করা সহজ করে দিন। 429 Too Many Requests রিটার্ন করুন এবং কয়েকটি স্ট্যান্ডার্ড হেডার অন্তর্ভুক্ত করুন:
X-RateLimit-Limit: উইন্ডোতে সর্বোচ্চ অনুমতিপ্রাপ্তX-RateLimit-Remaining: কতগুলো বাকি আছেX-RateLimit-Reset: উইন্ডো কখন রিসেট হবে (টাইমস্ট্যাম্প বা সেকেন্ড)Retry-After: রিট্রাই করার আগে কতক্ষণ অপেক্ষা করতে হবে
ক্লায়েন্টরা 429-কে একটি স্বাভাবিক অবস্থা হিসেবে বিবেচনা করা উচিত, এটি একটি ত্রুটি যাকে লড়াই করা উচিত নয়। একটি ভদ্র রিট্রাই প্যাটার্ন উভয়ের জন্যই ভালো:
Retry-Afterথাকলে সেটার জন্য অপেক্ষা করুন- না থাকলে এক্সপোনেনশিয়াল ব্যাকঅফ ব্যবহার করুন (উদাহরণ 1s, 2s, 4s)
- কিছু র্যান্ডোমনেস (জিটার) যোগ করুন যাতে অনেক ক্লায়েন্ট একসাথে রিট্রাই না করে
- অপেক্ষার সময় সীমা রাখুন (উদাহরণ 30-60s)
উদাহরণ: যদি কোনো গ্রাহক রাতের সিঙ্ক চালায় যা আপনার API-কে বাড়তি চাপ দেয়, তাদের কাজ মিনিট জুড়ে অনুরোধ ছড়িয়ে দিতে পারে এবং 429 এ ধরা পড়লে পুরো রান ব্যর্থ করার পরিবর্তে ধীর হতে পারে।
ত্রুটি, স্ট্যাটাস কোড, এবং নিরাপদ লেখালেখি
আপনার API ত্রুটিগুলো পড়তে কঠিন হলে সাপোর্ট টিকিট দ্রুত বাড়ে। একটি ত্রুটি শেপ বেছে নিন এবং সর্বত্র তা বজায় রাখুন, 500-সমেত। একটি সরল স্ট্যান্ডার্ড হলো: code, message, details, এবং একটি request_id যা ব্যবহারকারী সাপোর্ট চ্যাটে পেস্ট করতে পারে।
এখানে একটি ছোট, পূর্বানুমানযোগ্য ফরম্যাট:
{
"error": {
"code": "validation_error",
"message": "Some fields are invalid.",
"details": {
"fields": [
{"name": "email", "issue": "must be a valid email"},
{"name": "plan", "issue": "must be one of: free, pro, business"}
]
},
"request_id": "req_01HT..."
}
}
HTTP স্ট্যাটাস কোডগুলো একইভাবে ব্যবহার করুন: 400 খারাপ ইনপুটের জন্য, 401 যখন অথ নেই বা অবৈধ, 403 যখন ব্যবহারকারী অথ আছে কিন্তু অনুমতি নেই, 404 যখন রিসোর্স পাওয়া যায় না, 409 কনফ্লিক্ট (যেমন ডুপ্লিকেট ইউনিক ভ্যালু বা ভুল স্টেট), 429 রেট লিমিট, এবং 500 সার্ভার ত্রুটি। ধারাবাহিকতা বুদ্ধিমত্তার চেয়ে বেশি মূল্যবান।
ভ্যালিডেশন ত্রুটিগুলো ঠিক করাটা সহজ করুন। ফিল্ড-স্তরের হিন্টগুলো সেই এক্সটের্নাল প্যারাম নাম দেখাক যা আপনার ডকসে আছে, অভ্যন্তরীণ ডাটাবেস কলামের নাম নয়। যদি কোনো ফরম্যাট রিকোয়ার করা হয় (তারিখ, কারেন্সি, এনাম), বলুন আপনি কী গ্রহণ করবেন এবং একটি উদাহরণ দেখান।
রিট্রাইগুলোই অনেক API-তে দুর্ঘটনাকালীনভাবে ডুপ্লিকেট ডেটা তৈরি করে। গুরুত্বপূর্ণ POST অ্যাকশনের জন্য (পেমেন্ট, ইনভয়েস তৈরি, ইমেইল পাঠানো) idempotency কীগুলো সমর্থন করুন যাতে ক্লায়েন্টরা নিরাপদে রিট্রাই করতে পারে।
- নির্দিষ্ট POST এন্ডপয়েন্টে
Idempotency-Keyহেডার গ্রহণ করুন। - ফলাফলসহ ওই কী সংরক্ষণ করুন একটি ছোট উইন্ডোর জন্য (উদাহরণ 24 ঘণ্টা)।
- পুনরাবৃত্ত কী-তে প্রথম রিকোয়েস্টের মতো একই রেসপন্স দিন।
- যদি প্রথম রিকোয়েস্টটি এখনও চলছে, একটি স্পষ্ট "আবার চেষ্টা করুন" রেসপন্স দিন দ্বিতীয় রিসোর্স তৈরি করার বদলে।
এই এক হেডার নেটওয়ার্কের সমস্যা বা ক্লায়েন্ট টাইমআউটের সময় অনেক কষ্টের এজ কেস প্রতিরোধ করে।
উদাহরণ পরিস্থিতি: একটি ছোট SaaS বিলিং API বাস্তবে
ধরা যাক আপনি একটি সরল SaaS চালান যার তিনটি মূল অবজেক্ট: projects, users, এবং invoices। একটি প্রোজেক্টে অনেক ব্যবহারকারী থাকতে পারে, এবং প্রতিটি প্রোজেক্ট মাসিক ইনভয়েস পায়। ক্লায়েন্টরা ইনভয়েসগুলো তাদের অ্যাকাউন্টিং টুলে সিঙ্ক করতে চায় এবং তাদের নিজস্ব অ্যাপে বেসিক বিলিং দেখাতে চায়।
একটি পরিচ্ছন্ন v1 এরকম হতে পারে:
GET /v1/projects/{project_id}
GET /v1/projects/{project_id}/invoices
POST /v1/projects/{project_id}/invoices
এখন একটি ব্রেকিং চেঞ্জ ঘটে। v1-এ আপনি ইনভয়েস পরিমাণ সেন্টে একটি ইন্টেজার হিসেবে রাখেন: amount_cents: 1299। পরে, আপনি মাল্টি-কারেন্সি এবং দশমিক দরকার হবে, তাই আপনি চান amount: "12.99" এবং currency: "USD"। যদি আপনি পুরোনো ফিল্ড ওভাররাইট করেন, প্রতিটি বিদ্যমান ইন্টিগ্রেশন ভাঙে। ভার্সনিং প্যানিক এড়ায়: v1 স্থিতিশীল রাখুন, /v2/... নতুন ফিল্ডসহ পাঠান, এবং ক্লায়েন্টরা মাইগ্রেট করা পর্যন্ত উভয়কে সমর্থন করুন।
ইনভয়েস তালিকা করার জন্য একটি পূর্বানুমানযোগ্য পেজিনেশন শেপ ব্যবহার করুন। উদাহরণ:
GET /v1/projects/p_123/invoices?limit=50\u0026cursor=eyJpZCI6Imludl85OTkifQ==
200 OK
{
"data": [ {"id":"inv_1001"}, {"id":"inv_1000"} ],
"next_cursor": "eyJpZCI6Imludl8xMDAwIn0="
}
একদিন একটি গ্রাহক একটি লুপে ইনভয়েস ইম্পোর্ট করে এবং আপনার রেট লিমিটে পড়ে। এলোমেলো ব্যর্থতার বদলে, তারা একটি স্পষ্ট রেসপন্স পায়:
429 Too Many RequestsRetry-After: 20- একটি ছোট ত্রুটি বডি যেমন
{ "error": { "code": "rate_limited" } }
তাদের পাশেই ক্লায়েন্ট 20 সেকেন্ড অপেক্ষা করে, তারপর একই cursor থেকে চালিয়ে যেতে পারে আবার সবকিছু পুনরায় ডাউনলোড বা ডুপ্লিকেট ইনভয়েস তৈরি না করে।
ধাপে ধাপে: আপনার v1 API-র জন্য একটি সরল রিলিজ প্ল্যান
একটি v1 লঞ্চ তখনই ভাল হয় যখন আপনি এটাকে একটি ছোট প্রোডাক্ট রিলিজ হিসেবে বিবেচনা করেন, শুধুমাত্র এন্ডপয়েন্টের বান্ডল নয়। লক্ষ্যটি সরল: মানুষ এতে নির্মাণ করতে পারে, এবং আপনি বিনা আশঙ্কায় এটি উন্নত করতে পারেন।
একটি বাস্তবসম্মত 1-সপ্তাহের প্ল্যান (ছোট টিমের জন্যও)
একটি পাতা লিখে শুরু করুন যা ব্যাখ্যা করে আপনার API কী জন্য এবং কী নয়। সারফেসেটা এতোটাই ছোট রাখুন যে আপনি এটা মুখে এক মিনিটে ব্যাখ্যা করতে পারেন।
এই ক্রম অনুসরণ করুন এবং প্রতিটি ধাপ পর্যাপ্ত হওয়ার আগ পর্যন্ত এগোবেন না:
- একটি সিঙ্গেল-পেজ স্পেসিফ লিখুন যা আপনার কোর রিসোর্স এবং প্রথম কিছু এন্ডপয়েন্ট (৫-১০টি চিন্তা করুন) নামকরণ করে। বেস URL প্যাটার্ন, অথ পদ্ধতি, এবং প্রয়োজনীয় হেডার অন্তর্ভুক্ত করুন।
- প্রতিটি এন্ডপয়েন্টের জন্য একটি বাস্তবসম্মত রিকোয়েস্ট এবং একটি বাস্তবসম্মত রেসপন্স লিখুন। আসল ফিল্ড নাম ব্যবহার করুন যা আপনি চালু করতে যাচ্ছেন। এই উদাহরণগুলো আপনার প্রথম ডকস এবং প্রথম টেস্ট হয়ে যাবে।
- একটি সংক্ষিপ্ত নিয়ম সেকশন যোগ করুন: ত্রুটিগুলো কেমন দেখায়, পেজিনেশন কিভাবে কাজ করে (যদি কোনো লিস্ট এন্ডপয়েন্ট থাকে), রেট লিমিট কী, এবং কোন ফিল্ডগুলো স্থিতিশীল বনাম পরিবর্তনশীল।
- একটি অভ্যন্তরীণ টেস্ট করুন একটি নকল ক্লায়েন্ট দিয়ে। নিজেকে গ্রাহক ভেবে একটি নতুন রিপোতে ইন্টিগ্রেশন বানানোর ভান করুন। প্রথম সফল কলটি পেতে কত সময় লাগলো তা নোট করুন, এবং কোথায় আপনি বিভ্রান্ত হয়েছিলেন তা লিপিবদ্ধ করুন।
- আপনার v1 কনট্র্যাক্ট প্রকাশ করুন: কী পরিবর্তন নিরাপদ (অ্যাডিটিভ ফিল্ড), কী পরিবর্তন নতুন ভার্সন দাবি করে, এবং ব্রেকিং চেঞ্জের জন্য আপনি কত নোটিশ দেবেন।
যদি আপনি কোড-জেনারেটিং ওয়ার্কফ্লো ব্যবহার করেন (উদাহরণস্বরূপ Koder.ai দিয়ে এন্ডপয়েন্ট ও রেসপন্স স্ক্যাফোল্ড করা), তবুও নকল- ক্লায়েন্ট টেস্টটি করুন। জেনারেট করা কোড দেখতে ঠিক মনে হলেও ব্যবহারিক দিক থেকে ঝামেলাজনক হতে পারে।
ফলাফল হলো কম সাপোর্ট ইমেইল, কম হটফিক্স রিলিজ, এবং এমন একটি v1 যা আপনি বাস্তবে বজায় রাখতে পারবেন।
ওভার-ইঞ্জিনিয়ার না করে একটি ছোট SDK পাঠানো
একটি প্রথম SDK হচ্ছে দ্বিতীয় কোনো প্রোডাক্ট নয়। এটাকে HTTP API-এর উপর একটি পুরুতর, বন্ধুত্বপূর্ণ র্যাপার হিসেবে ভাবুন। এটি সাধারণ কলগুলোকে সহজ করা উচিত, কিন্তু API কিভাবে কাজ করে তা লুকিয়ে রাখা উচিত নয়। যদি কেউ এমন একটি ফিচার ব্যবহার করতে চায় যেটা আপনি এখনো র্যাপ করেননি, তাদেরকে কাঁচা রিকোয়েস্টে নামার সুবিধা থাকা উচিত।
একটি ভাষা বেছে নিন প্রথমে, গ্রাহকরা বাস্তবে কোনটা ব্যবহার করে তার ভিত্তিতে। অনেক B2B SaaS API-র জন্য সেটা সাধারণত JavaScript/TypeScript বা Python। একটায় শক্তিশালী SDK পাঠানো তিনটি অর্ধ-শেষ SDK পাঠানো থেকে শ্রেয়।
একটি ছোট SDK-তে কী থাকা উচিত
একটি ভাল স্টার্টার সেট হলো:
- অথ হ্যান্ডলিং (API কী বা OAuth টোকেন) একটি জায়গায়
- যুক্তিসংগত টাইমআউট এবং নিরাপদ রিকোয়েস্টগুলোর জন্য অটোম্যাটিক রিট্রাই, ব্যাকঅফসহ
- পেজিনেশন হেল্পার যা একটি ইটারেটর বা পরবর্তী পৃষ্ঠা ফাংশন রিটার্ন করে
- পরিষ্কার রিকোয়েস্ট/রেসপন্স মডেল (ভিতরে সহজ টাইপ হলেও)
- কাস্টম হেডার এবং র কেন HTTP কলগুলোর জন্য একটি এস্কেপ হ্যাচ
আপনি এটা হাতে লিখতে পারেন বা OpenAPI স্পেক থেকে জেনারেট করতে পারেন। জেনারেশন চমৎকার যখন আপনার স্পেক সঠিক থাকে এবং আপনি ধারাবাহিক টাইপিং চান, কিন্তু এটি প্রাথমিকভাবে অনেক কোড উত্পন্ন করে। শুরুতে হাতে লেখা একটি মিনিমাল ক্লায়েন্ট প্লাস ডকসের জন্য একটি OpenAPI ফাইল সাধারণত যথেষ্ট। পরে আপনি জেনারেটেড ক্লায়েন্টে স্যুইচ করতে পারেন যদি পাবলিক SDK ইন্টারফেস স্থিতিশীল থাকে।
SDK-কে আলাদা করে ভার্সন করুন
আপনার API ভার্সন আপনার কম্প্যাটিবিলিটি নিয়ম অনুসরণ করবে। আপনার SDK-ভার্সন প্যাকেজিং নিয়ম অনুসরণ করবে।
নতুন ঐচ্ছিক প্যারামিটার বা নতুন এন্ডপয়েন্ট যোগ করলে সাধারণত এটা একটি মাইনর SDK বাম্প। SDK-তে বড় রিলিজ রিজার্ভ করুন ব্রেকিং চেঞ্জের জন্য (পদ্ধতির নাম বদলানো, ডিফল্ট পরিবর্তন), এমনকি API একই থাকলেও। এই বিভাজন আপগ্রেডগুলো শীতল এবং সাপোর্ট টিকিটগুলো কম রাখে।
সাধারণ ভুলগুলো যা সাপোর্ট মাথাব্যথা দেয়
অধিকাংশ API সাপোর্ট টিকিট বাগ নিয়ে নয়। এগুলো বিস্ময়ের কারণে হয়। পাবলিক API ডিজাইন মূলত বিরক্তিকর ও পূর্বানুমানযোগ্য হওয়ার ব্যাপার যাতে ক্লায়েন্ট কোড মাস ধরে কাজ করে।
দ্রুততম উপায় বিশ্বাস হারানোর হলো রেসপন্স পরিবর্তন করা কোনো খোঁচা না দিয়ে। যদি আপনি একটি ফিল্ডের নাম বদলান, টাইপ পরিবর্তন করুন, বা যেখানে আগে মান ফিরত সেখানে এখন null ফিরানো শুরু করুন, আপনি ক্লায়েন্টকে এমনভাবে ভাঙিয়ে দেবেন যা তাদের নির্ণয় কঠিন করে। যদি সত্যিই আচরণ পরিবর্তন করতে হয়, ভার্সনিং করুন, অথবা নতুন একটি ফিল্ড যোগ করুন এবং পুরোনোটি কিছু সময় রেখে স্পষ্ট সানশেট প্ল্যান দিন।
পেজিনেশন আরেকটি বারবার হওয়া সমস্যা। সমস্যা তখন দেখা দেয় যখন এক এন্ডপয়েন্ট page/pageSize ব্যবহার করে, অন্যটি offset/limit, আর তৃতীয়টি কার্সর ব্যবহার করে, সবকটির ভিন্ন ডিফল্ট থাকে। v1-এর জন্য একটি প্যাটার্ন বেছে নিন এবং সব জায়গায় সেটাই রাখুন। সোর্টিংও স্থিতিশীল রাখুন যাতে পরের পৃষ্ঠা আইটেম স্কিপ বা রিপিট না করে যখন নতুন রেকর্ড আসে।
ত্রুটিগুলো অনেক ব্যাক-ফর্থ সৃষ্টি করে যখন সেগুলো অসমঞ্জস। একটি সাধারণ ব্যর্থতা মোড হলো এক সার্ভিস { "error":"..." } ফেরত দেয় এবং অন্যটি { "message":"..." }, এবং একই সমস্যার জন্য ভিন্ন HTTP স্ট্যাটাস কোড। তখন ক্লায়েন্টরা এন্ডপয়েন্ট-নির্দিষ্ট হ্যন্ডলার বানায়।
নিচে পাঁচটি ভুল যা সবচেয়ে দীর্ঘ ইমেইল থ্রেড তৈরি করে:
- নাম/টাইপ/অর্থ বদলের মতো নীরব ফিল্ড পরিবর্তন বিনা ভার্সন বাম্প বা ডিপ্রেকশন উইন্ডো ছাড়া
- এন্ডপয়েন্টভিত্তিক বা সময়ের সাথে পেজিনেশন রুল বদলানো
- এন্ডপয়েন্ট জুড়ে বিভিন্ন ত্রুটি ফরম্যাট, স্ট্যাটাস কোড বা ভ্যালিডেশন মেসেজ
- অনুরোধ আইডি অনুপস্থিত, ফলে উভয় পক্ষই লগ থেকে নির্দিষ্ট ব্যর্থ কল দ্রুত খুঁজে পায় না
- হঠাৎ রেট লিমিট যা হেডার দেয় না, স্পষ্ট রিট্রাই নির্দেশ দেয় না, এবং কোনো ব্যাকঅফ উদাহরণ নেই
একটি সরল অভ্যাস সাহায্য করে: প্রতিটি রেসপন্সে একটি request_id থাকা উচিত, এবং প্রতিটি 429-এ রিট্রাই কখন করতে হবে তা বোঝানো উচিত।
দ্রুত চেকলিস্ট ও পরবর্তী ধাপ
কিছুই প্রকাশ করার আগে ধারাবাহিকতার উপর একটি চূড়ান্ত পাস করুন। বেশিরভাগ সাপোর্ট টিকিট ঘটে কারণ ছোট ছোট বিবরণ এন্ডপয়েন্ট, ডকস, এবং উদাহরণে মেলে না।
সবচেয়ে বেশি সমস্যা ধরার দ্রুত চেকগুলো:
- নামকরণ: ধারাবাহিক নাউন, পলুরাল রিসোর্স, এবং ফিল্ড কেসিং (একটি বেছে নিন এবং মানুন)।
- উদাহরণ: প্রতিটি এন্ডপয়েন্টের জন্য একটি বাস্তবসম্মত রিকোয়েস্ট এবং রেসপন্স, পেজিনেশনসহ।
- ত্রুটি: একটি পরিষ্কার ত্রুটি শেপ, স্থায়ী ত্রুটি কোড, এবং সাধারণ ব্যর্থতার জন্য সহায়ক মেসেজ।
- সীমা: রেট লিমিট আচরণ ডকুমেন্ট করা আছে এবং রেসপন্সে প্রত্যাশিত হেডার রয়েছে।
- নিরাপত্তা: ক্রিয়েটগুলোর জন্য idempotency এবং টাইমআউটগুলোর পূর্বানুমানযোগ্য হ্যান্ডলিং।
লঞ্চের পরে, আপনি যে জিনিসগুলো মানুষ আসলে ব্যবহার করছে তা দেখুন, আপনি যা আশা করেছিলেন তা নয়। প্রথমদিকে একটি ছোট ড্যাশবোর্ড এবং সাপ্তাহিক পর্যালোচনা যথেষ্ট।
প্রথম নজরে মনিটর করুণ:
- 429 স্পাইক (কে সীমিত হচ্ছে এবং কেন)
- প্রতিটি এন্ডপয়েন্টের p95 লেটেন্সি (ধীর এন্ডপয়েন্টগুলো প্রায়ই N+1 কুয়েরি লুকায়)
- শীর্ষ এন্ডপয়েন্ট ও প্যারামিটার (আপনার প্রকৃত API সারফেস)
- স্ট্যাটাস কোড অনুযায়ী ত্রুটি অনুপাত (400 বনাম 401 বনাম 500)
- টাইমআউট ও রিট্রাই (ক্লায়েন্ট হয়তো বারবার লুপ করছে)
ফিডব্যাক সংগ্রহ করুন সবকিছু সংস্কারের জন্য নয়। ডকসে একটি সংক্ষিপ্ত রিপোর্ট অন ইস্যু পাথ যোগ করুন, এবং প্রতিটি রিপোর্টে এন্ডপয়েন্ট, request id, এবং ক্লায়েন্ট ভার্সন ট্যাগ করুন। কিছু ঠিক করলে, অ্যাডিটিভ পরিবর্তন অগ্রাধিকার দিন: নতুন ফিল্ড, নতুন ঐচ্ছিক প্যারামিটার, বা নতুন এন্ডপয়েন্ট—বিদ্যমান আচরণ ভাঙার পরিবর্তে।
পরবর্তী ধাপ: একটি এক-পৃষ্ঠার API স্পেক লিখুন আপনার রিসোর্স, ভার্সনিং পরিকল্পনা, পেজিনেশন বিধি, এবং ত্রুটি ফরম্যাটসহ। তারপর ডকস ও একটি নগণ্য স্টার্টার SDK তৈরি করুন যা অথ ও ২-৩ মূল এন্ডপয়েন্ট কভার করে। দ্রুতগামী হতে চাইলে, আপনি একটি চ্যাট-ভিত্তিক পরিকল্পনা ব্যবহার করে স্পেক, ডকস, এবং স্টার্টার SDK খসড়া করতে পারেন Koder.ai-এর মতো টুল ব্যবহার করে (এর প্ল্যানিং মোড এন্ডপয়েন্ট ও উদাহরণ ম্যাপ করার জন্য উপকারী)।
সাধারণ প্রশ্ন
প্রথম পাবলিক API-তে কতগুলি এন্ডপয়েন্ট প্রকাশ করা উচিত?
5–10টি এন্ডপয়েন্ট দিয়ে শুরু করুন যা বাস্তব গ্রাহক ক্রিয়ার সাথে মেলে।
একটি ভালো নিয়ম: যদি আপনি একটি রিসোর্স এক বাক্যে বোঝাতে না পারেন (এটা কী, কে মালিক, কীভাবে ব্যবহৃত হয়), সেটা পাবলিক করা পর্যন্ত প্রাইভেট রাখুন যতক্ষণ না ব্যবহারে স্পষ্টতা আসে।
SaaS API-এর জন্য কোন রিসোর্সগুলো দিয়ে শুরু করা উচিত?
গ্রাহকরা কথোপকথনে যেসব নাম ব্যবহার করে এমন একটি ছোট সেট স্থিতিশীল নাম (রিসোর্স) বেছে নিন, এবং এমন নামগুলো স্থিতিশীল রাখুন যেহেতু আপনার ডাটাবেস বদলালেও।
SaaS-এর সাধারণ স্টার্টারগুলো হল users, organizations, projects, এবং events—নিশ্চিত চাহিদা না এলে পরে বাড়ান।
কোন HTTP মেথডগুলো ব্যবহার করা উচিত, এবং কেন এটি গুরুত্বপূর্ণ?
স্ট্যান্ডার্ড অর্থই ব্যবহার করুন এবং ধারাবাহিক থাকুন:
GET= পড়া (কোনো সাইড এফেক্ট নেই)POST= তৈরি বা কোনো অ্যাকশন শুরু করাPATCH= আংশিক আপডেটDELETE= মুছে ফেলা বা অক্ষম করা
প্রধান সুবিধা হলো পূর্বানুমানযোগ্যতা: ক্লায়েন্টরা কী হবে তা অনুমান না করে।
আমার API-কে URL-এ ভার্সন করা উচিত নাকি হেডারে?
ডিফল্ট হিসেবে URL ভার্সনিং ব্যবহার করুন যেমন /v1/...।
এটি লগ ও স্ক্রীনশট-এ দেখা সহজ, গ্রাহকের সাথে ডিবাগ করা সহজ, এবং ভাঙনীয় পরিবর্তন হলে v1 ও v2 পাশাপাশি চালানো সহজ করে।
API-এ কীকে ব্রেকিং চেঞ্জ বলা যায়?
যদি একটি সঠিক ক্লায়েন্ট কোন কোড বদল না করেই ব্যর্থ হতে পারে, সেটাই ব্রেকিং চেঞ্জ। সাধারণ উদাহরণগুলো:
- ফিল্ডের নাম বদলানো
- ফিল্ড টাইপ বা অর্থ বদলানো
- ফিল্ড বা এন্ডপয়েন্ট অপসারণ
- আগে ঐচ্ছিক ছিল এমন ইনপুট এখন প্রয়োজনীয় করা
- অথেন্টিকেশন বা ডিফল্ট পারমিশন বদলানো
একটি নতুন ঐচ্ছিক ফিল্ড যোগ করা সাধারণত নিরাপদ।
v1 API-এর জন্য বাস্তবসম্মত ডিপ্রেকেশন নীতি কী?
সরল রাখুন:
- আগে জানিয়ে দিন
- রেসপন্সে স্পষ্ট ওয়ার্নিং দিন
- একটি শেষ তারিখ নির্ধারণ করুন
প্রথম API-র জন্য একটি বাস্তবসম্মত ডিফল্ট হলো 90 দিনের জানালা যাতে গ্রাহকরা মাইগ্রেট করতে পারে।
আমি কি পেজ-ভিত্তিক নাকি কারসর-ভিত্তিক পেজিনেশন ব্যবহার করব?
ভাগ করে নিন এবং ভাড়া দিন — এক প্যাটার্ন বেছে নিয়ে অ্যাপ জুড়ে সেটাই ব্যবহার করুন।
- page/limit ব্যবহার করুন যখন ডেটাসেট ছোট এবং লোকেরা মাঝে মাঝে পৃষ্ঠা 3 দেখতে চায়।
- cursor ব্যবহার করুন যখন তালিকা বড়, নতুন আইটেম আসছে, বা অনেক ফিল্টার/সোর্ট আছে।
সবসময় ডিফল্ট সোর্ট এবং টাই-ব্রেকার (যেমন created_at + id) নির্ধারণ করুন যাতে রেজাল্ট স্থিতিশীল থাকে।
কত রেট লিমিট সেট করা উচিত, এবং 429 এ কি ফেরত দেব?
একটি পরিষ্কার প্রতি-কী লিমিট দিয়ে শুরু করুন (উদাহরণস্বরূপ 60 অনুরোধ/মিনিট প্লাস সামান্য বরস্ট), তারপর বাস্তব ট্র্যাফিক দেখে অনুকূল করুন।
লিমিট হলে 429 রিটার্ন করুন এবং অন্তর্ভুক্ত করুন:
X-RateLimit-LimitX-RateLimit-RemainingX-RateLimit-ResetRetry-After
এতে রিট্রাই পূর্বানুমানযোগ্য হয় এবং সাপোর্ট টিকিট কমে।
একটি ভাল API ত্রুটি রেসপন্স কেমন হওয়া উচিত?
সার্ভিস জুড়ে একটি ত্রুটি ফরম্যাট ব্যবহার করুন (500 সহ)। একটি ব্যবহারিক শেপ হলো:
code(স্থায়ী আইডেন্টিফায়ার)message(মানব-পাঠযোগ্য)details(ফিল্ড-স্তরের সমস্যা)request_id(সাপোর্টের জন্য)
স্ট্যাটাস কোডগুলোও ধারাবাহিক রাখুন (400/401/403/404/409/429/500) যাতে ক্লায়েন্টরা পরিষ্কারভাবে হ্যান্ডেল করতে পারে।
কীভাবে ডকস এবং ছোট একটি SDK ছাড়া ওভার-ইঞ্জিনিয়ারিং না করে পাঠাব?
অনেক এন্ডপয়েন্ট দ্রুত জেনারেট করলে (উদাহরণ: Koder.ai) পাবলিক সারফেস ছোট রাখুন এবং এটিকে দীর্ঘমেয়াদী চুক্তি হিসেবে বিবেচনা করুন।
লঞ্চের আগে করুন:
- প্রতিটি এন্ডপয়েন্টের জন্য একটি বাস্তবসম্মত রিকোয়েস্ট + রেসপন্স উদাহরণ লিখুন
- পেজিনেশন ও ত্রুটি শেপ লক করুন
- গুরুত্বপূর্ণ
POST-এ Idempotency-Key যোগ করুন - একটি “ফেক ক্লায়েন্ট” অভ্যন্তরীণভাবে টেস্ট করুন
তারপর একটি ছোট SDK প্রকাশ করুন যাতে অথ, টাইমআউট, নিরাপদ রিকোয়েস্টগুলোর রিট্রাই, এবং পেজিনেশন সহজ হয়—কিন্তু HTTP কিভাবে কাজ করে সেটা লুকায় না।