দলগত সহযোগিতা FAQ: চুক্তি, কনফিগ ও ফিক্সচার
সংক্ষেপে: নামকরণ শৈলী, সময়ের ফরম্যাট, null সেমান্টিক্স, এনাম আকৃতি, কনফিগ ফরম্যাট, ফিক্সচার সংগঠন ও মার্জ কনফ্লিক্ট — দলে সত্যিই যে বারোটি সমঝোতা নিয়ে তর্ক হয়।

মূল কথা: দলের প্রথায় এসব একবার নিষ্পত্তি করুন — HTTP স্টেটাস কোডসহ {"data":…,"meta":…} এনভেলপ, সাইটজুড়ে এক নামকরণ শৈলী, টাইম জোনসহ RFC 3339 টাইমস্ট্যাম্প, আর স্ট্রিং এনাম — তারপর প্রতিটি নতুন API একই চুক্তির বিরুদ্ধে কেবল ফিল্ড যোগ করে বিকশিত করুন, কখনো বদলে বা মুছে নয়।
এসব প্রশ্নের একক সঠিক উত্তর নেই, কিন্তু দলের একক উত্তর থাকতেই হবে — নাহলে প্রতিটি নতুন API একই তর্ক আবার শুরু করে।
১. API চুক্তি
API কেমন কাঠামো ফেরত দেবে?
তিন প্রচলিত আকৃতি, প্রতিটির একটি দাম:
| আকৃতি | উদাহরণ | সুবিধা | অসুবিধা |
|---|---|---|---|
| কাঁচা ডেটা | [{...}, {...}] |
সরল | মেটাডেটা বহন করতে পারে না |
| নির্দিষ্ট এনভেলপ | {"code":0,"message":"ok","data":{...}} |
সমান এরর হ্যান্ডলিং | ব্যবসায়িক কোড HTTP স্টেটাসের নকল করে |
| রিসোর্স এনভেলপ | {"data":{...},"meta":{...},"links":{...}} |
সম্প্রসারণযোগ্য, স্পষ্ট সেমান্টিক্স | আরেক স্তর নেস্টিং |
অভ্যন্তরীণ ব্যবসায়িক API-তে "রিসোর্স এনভেলপ + ফল প্রকাশকারী HTTP স্টেটাস কোড"-কে অগ্রাধিকার দিন:
{
"data": [{ "id": "1", "name": "নমুনা" }],
"meta": { "total": 128, "page": 2, "pageSize": 20 }
}
এররের জন্য আরেকটি code নেস্ট না করে HTTP স্টেটাস কোড প্লাস কাঠামোগত এরর বডি ব্যবহার করুন:
{
"error": {
"type": "validation_failed",
"message": "রিকোয়েস্ট প্যারামিটার যাচাই ব্যর্থ",
"details": [
{ "path": "/email", "reason": "ফরম্যাট ভুল" }
]
}
}
মূল বিষয়: HTTP স্টেটাস কোড ইতিমধ্যে সফলতা বা ব্যর্থতা প্রকাশ করে, তাই ব্যবসায়িক কোড বাড়তি। দুই সিস্টেম একসঙ্গে থাকলে "২০১ কিন্তু code ৫০০" ধরনের অসামঞ্জস্য প্রায় অনিবার্য।
খালি অ্যারে এড়ান। টপ লেভেলে অ্যারে থাকলে পেজিনেশন, মোট বা কার্সর জোড়া লাগানো যায় না, আর পরে যোগ করা মানে প্রতিটি কলার বদলানো।
ফিল্ড-নাম snake_case নাকি camelCase?
একটি বাছুন, সাইটজুড়ে প্রয়োগ করুন, আর কখনো এক JSON ডকুমেন্টে মিশাবেন না।
| শৈলী | সাধারণ ইকোসিস্টেম | উদাহরণ |
|---|---|---|
camelCase |
JavaScript / TypeScript / Java | userName, createdAt |
snake_case |
Python / Ruby / Go (আংশিক) / ডেটাবেস কলাম | user_name, created_at |
kebab-case |
বিরল; হাইফেনযুক্ত কি অ্যাক্সেস করা বিশ্রী | user-name |
মানদণ্ড:
- এই JSON কে ভোগ করে: ফ্রন্টএন্ড প্রধান হলে camelCase, ডেটা পাইপলাইন ও Python সার্ভিস প্রধান হলে snake_case;
- ডেটাবেস কলামে সরাসরি ম্যাপ করে কি: টেবিল কাঠামো সোজা পাঠালে snake_case একটি রূপান্তর স্তর বাঁচায়;
- বিদ্যমান সিস্টেমের ধারাবাহিকতা: বিদ্যমান API যা ব্যবহার করে তা রাখুন; সামঞ্জস্য শুদ্ধতার চেয়ে বড়।
সত্যিই রূপান্তর দরকার হলে সীমানায় করুন (গেটওয়ে বা ফ্রন্টএন্ড রিকোয়েস্ট স্তর), ব্যবসায়িক কোডে ছড়িয়ে toCamelCase কল না করে।
সময় ফিল্ডে কোন ফরম্যাট?
টাইম জোন অফসেটসহ RFC 3339 / ISO 8601 স্ট্রিং ব্যবহার করুন:
{
"createdAt": "2026-10-30T11:37:57+08:00",
"updatedAt": "2026-10-30T03:37:57Z"
}
মূল বিষয়:
- টাইম জোন রাখুন:
2026-10-30 11:37:57জোন ছাড়া ক্রস-টাইম-জোন পরিস্থিতিতে অগত্যা ভাঙবে; Zবা অফসেট সমানভাবে ব্যবহার করুন: দুটোই সঠিক, কিন্তু এক API-তে মিশাবেন না;- সংখ্যিক টাইমস্ট্যাম্প এড়ান: সেকেন্ড নাকি মিলিসেকেন্ড, লিপ সেকেন্ড আছে কি না — প্রতিটি দলকে আবার ব্যাখ্যা করতে হয়। সংক্ষিপ্ততা দরকার হলে মিলিসেকেন্ড ইন্টিজার ব্যবহার করুন, কিন্তু ডকুমেন্টেশনে একক পিন করুন।
createdAt / updatedAt / deletedAt-এর মতো At সাফিক্সযুক্ত ফিল্ড-নাম পছন্দ করুন,
যাতে এক নজরে বোঝা যায় মান একটি সময়বিন্দু, সময়কাল নয়। সময়কালের জন্য timeoutMs, ttlSeconds — একক নামের ভেতরে রাখুন।
null কি null হবে নাকি ফিল্ড বাদ?
এটি নির্ভর করে "এই ফিল্ড অর্থবহ কি না"-এর উপর:
| সেমান্টিক্স | রূপ | নোট |
|---|---|---|
| ফিল্ড আছে কিন্তু এখনও মান নেই | "name": null |
স্পষ্টভাবে বলে "দেখা হয়েছে আর খালি" |
| ফিল্ড এই রিসোর্সের সঙ্গে অপ্রাসঙ্গিক | বাদ দিন | যেমন সাধারণ ব্যবহারকারীর vipExpireAt থাকা উচিত নয় |
| আংশিক হালনাগাদ (PATCH) | বাদ = পরিবর্তন নয় | এখানে কেবল null মানে "মুছে ফেলা" |
তৃতীয় ক্ষেত্রটি সবচেয়ে উপেক্ষিত। PATCH রিকোয়েস্টে:
{ "nickname": null }
এর মানে "nickname মুছে ফেলো", অথচ রিকোয়েস্ট বডি থেকে nickname বাদ দিলে মানে "nickname ছুঁবে না"।
দুটোই "মুছে ফেলা" ধরলে যে ব্যবহারকারী ইমেইল বদলায় তার nickname মুছে যাবে।
আরেকবার: undefined ব্যবহার করবেন না। এটি বৈধ JSON মান নয়, আর JSON.stringify কি পুরো ফেলে দেয়,
তাই আচরণ "বাদ দেওয়া"-র সঙ্গে মেলে অথচ কোড দেখায় "স্পষ্টভাবে খালি মান পাঠানো হয়েছে"।
বুলিয়ান ফিল্ডের নাম কেমন হওয়া উচিত?
is / has / can / should প্রিফিক্স ব্যবহার করুন আর নেতিবাচক রূপ এড়ান।
{
"isActive": true,
"hasPassword": false,
"canEdit": true
}
তিন শিক্ষা:
- নেতিবাচক নয়:
isDisabled: falseপাঠককে একবার উল্টাতে বাধ্য করে;isEnabled: trueসরাসরি। দ্বিগুণ নেতিবাচক (isNotDisabled) বিপর্যয়; - বুলিয়ানে সংখ্যা নয়:
"enabled": 1প্রতিটি ভোক্তাকে একবার=== 1লিখতে বাধ্য করে; - স্ট্রিং নয়:
"enable": "true"JavaScript-এ truthy, আরif (data.enable)"false"-এর জন্যও সত্য; এমন বাগ ট্রেস করা অত্যন্ত কঠিন।
এনাম ফিল্ডে সংখ্যা নাকি স্ট্রিং?
স্পষ্ট স্টোরেজ বা ব্যান্ডউইথ সীমাবদ্ধতা না থাকলে স্ট্রিং ব্যবহার করুন।
{ "status": "active" }
{ "status": 1 }-এর তুলনায় স্ট্রিং জেতে কারণ:
- লগ, প্যাকেট ক্যাপচার ও ডেটাবেস ম্যাপিং টেবিল না দেখেই সরাসরি পাঠযোগ্য;
- এনাম মান যোগ করলে বিদ্যমান মানের অর্থ বদলায় না (সংখ্যিক এনামের মাঝখানে মান ঢুকালে সব সরে যায়);
- ফ্রন্টএন্ডকে
1 → 'active'ম্যাপিং সিঙ্কে রাখতে হয় না।
দাম কয়েক বাড়তি বাইট, যা কম্প্রেশনের পর প্রায় অগ্রাহ্য।
সঙ্গী অভ্যাস: স্ট্রিং এনাম মানে ছোট হাতের অক্ষর + আন্ডারস্কোর (pending_review), আর Schema-তে enum দিয়ে বাধ্যতামূলক করুন
যাতে অবৈধ মান ভ্যালিডেশন স্তরেই প্রত্যাখ্যাত হয়।
২. কনফিগারেশন ও ফিক্সচার
কনফিগ JSON, YAML নাকি TOML হওয়া উচিত?
পছন্দ নয়, উদ্দেশ্য দিয়ে বাছুন:
| ফরম্যাট | উপযুক্ত | অনুপযুক্ত |
|---|---|---|
| JSON | প্রোগ্রামগত পড়া-লেখা, কঠোর কাঠামোগত ডেটা, Schema ভ্যালিডেশন | ঘন হাতে সম্পাদনা (কমেন্ট অনুমোদিত নয়) |
| YAML | গভীর নেস্টেড ডিপ্লয়মেন্ট কনফিগ (K8s) | হাতে লেখা ইনডেন্টেশন ভুলপ্রবণ; yes/no বুলিয়ান হয়ে যায় |
| TOML | সমতল নির্ভরতা ও টুল কনফিগ (Cargo.toml, pyproject.toml) |
গভীর নেস্টিংয়ে দুর্বল পাঠযোগ্যতা |
| JSONC | কমেন্ট দরকারি এডিটর কনফিগ (tsconfig.json) |
সিস্টেম সীমানা পার হওয়া |
দলে সাধারণ ভুল হলো ব্যবসায়িক কনফিগ YAML-এ রাখা — YAML-এর অন্তর্নিহিত টাইপ রূপান্তর (1.0 সংখ্যা হয়,
NO বুলিয়ান হয়, 2026-10-30 তারিখ হয়) পার্সারভেদে আলাদা ফল দেয়।
কনফিগ প্রোগ্রাম দিয়ে কঠোরভাবে যাচাই করতে হলে JSON + Schema বাছুন, আর কমেন্ট _comment ফিল্ড বা আলাদা ডকে ডকুমেন্ট করুন।
টেস্ট ফিক্সচার কীভাবে সাজানো উচিত?
"এক বেসলাইন + ন্যূনতম ডিফ" দিয়ে সাজান, প্রতিটি টেস্ট কেসের জন্য বিশাল JSON কপি করে নয়।
fixtures/
├─ users/
│ ├─ base.json # Baseline user object
│ ├─ no-email.json # Only email is missing
│ └─ invalid-age.json # Only age is out of range
└─ fixtures.ts # Utility functions for loading and shallow merging
import baseUser from './users/base.json';
export function makeUser(overrides: Partial<User> = {}): User {
return { ...baseUser, ...overrides };
}
তাতে নতুন টেস্ট কেসে কেবল ভিন্ন ফিল্ড লিখতে হয়, আর বেসলাইনের একটি ফিল্ড বদলালে সব কেস স্বয়ংক্রিয়ভাবে হালনাগাদ হয়।
তিন নিয়ম:
- ফিক্সচার Schema ভ্যালিডেশন পাস করুক: বেসলাইন ফিক্সচার নিজেই বৈধ ডেটা হওয়া উচিত;
- প্রোডাকশন থেকে বাস্তব ডেটা এক্সপোর্ট করবেন না: ফোন নম্বর, পরিচয়পত্র নম্বর ও ঠিকানা — সবই ব্যক্তিগত তথ্য;
- ফিক্সচার ভার্সন কন্ট্রোলে থাকুক কিন্তু ছোট থাকুক: একটি ফাইল কয়েক ডজন KB ছাড়ালে ছাঁটা বা জেনারেট করা দরকার।
JSON ফাইলে মার্জ কনফ্লিক্ট কীভাবে কমাব?
JSON সহজে কনফ্লিক্ট করে: ফরম্যাটার একবারে পুরো ফাইল রিফ্লো করে, তাই দুইজন একটি করে লাইন বদলালেও পুরো ফাইলে সংঘর্ষ হয়।
চার কৌশল:
- ফরম্যাটিং একীভূত করে
.editorconfig-এ যোগ করুন: সামঞ্জস্যপূর্ণ ইনডেন্টেশন, লাইন এন্ডিং ও পিচ্ছে নিউলাইন অপ্রাসঙ্গিক ডিফ এড়ায়; - কি সাজান: বর্ণানুক্রমিক ক্রমে একমত হন যাতে নতুন ফিল্ড অন্যের ইনসার্ট পয়েন্টের সঙ্গে সংঘর্ষ না করে;
- ফাইল ভাগ করুন: একটি বিশাল
config.json-কে ডোমেইন অনুযায়ী কয়েকটি ফাইলে ভাগ করুন, সংঘর্ষের পৃষ্ঠপোষকতা এমনিতেই কমে; - "সব রিফরম্যাট" কমিট এড়ান: ফরম্যাটিং ও ব্যবসায়িক পরিবর্তন দুই কমিটে আলাদা করুন যাতে রিভিউ পাঠযোগ্য থাকে।
দল লকফাইল ব্যবহার করলে (pnpm-lock.yaml, package-lock.json), হাতে মার্জ করবেন না; আবার জেনারেট করুন:
git checkout --theirs pnpm-lock.yaml
pnpm install
সংস্করণ সামঞ্জস্য কীভাবে রক্ষণাবেক্ষণ করব?
নীতি "যোগ করুন, বদলাবেন না, সরাবেন না"।
| পরিবর্তন | সামঞ্জস্য | পদ্ধতি |
|---|---|---|
| ঐচ্ছিক ফিল্ড যোগ | সামঞ্জস্যপূর্ণ | যোগ করুন; ভোক্তা অজানা ফিল্ড উপেক্ষা করে |
| বাধ্যতামূলক ফিল্ড যোগ | অসামঞ্জস্যপূর্ণ | সংস্করণ বাড়ান, বা ডিফল্ট দিন |
| ফিল্ড সরানো | অসামঞ্জস্যপূর্ণ | আগে ডেপ্রিকেটেড চিহ্নিত করুন, কলার দেখুন, তারপর সরান |
| ফিল্ড টাইপ বদলানো | অসামঞ্জস্যপূর্ণ | নতুন ফিল্ড-নাম যোগ করুন ও রূপান্তরকালে দুইটিতে লিখুন |
| এনাম মান-সেট বদলানো | নির্ভর করে | মান যোগ করা সামঞ্জস্যপূর্ণ; সরানো নয় |
সমর্থক ব্যবস্থা:
- ভোক্তা "শিথিল পার্সিং" ব্যবহার করে: অজানা ফিল্ড উপেক্ষা করে ও অনুপস্থিতের জন্য ডিফল্ট দেয়;
- সার্ভার কিছুকাল পুরোনো ফিল্ড রাখে আর রেসপন্সে
Deprecationহেডার ইঙ্গিত হিসেবে দেয়; - Schema-তে নতুন ফিল্ড
requiredচিহ্নিত করবেন না, আর ডেপ্রিকেটেড ফিল্ডেdeprecated: trueট্যাগ দিন।
CI-তে চুক্তি কীভাবে যাচাই করব?
Schema-কে কোডের অংশ ধরুন আর প্রতিটি কমিটে যাচাই করুন।
# Validate sample data against the Schema (using ajv-cli)
npx ajv-cli validate -s schemas/user.json -d "fixtures/users/*.json" --strict=false
CI-তে তিনটি জিনিস চালান:
- Schema নিজের বৈধতা:
$schemaঘোষণা বৈধ কি না,$refরেজলভ হয় কি না; - ফিক্সচার Schema-এর সঙ্গে মেলে কি না: টেস্ট ডেটা সরে না যায় নিশ্চিত করে;
- চুক্তি পশ্চাৎ-সামঞ্জস্যপূর্ণ কি না: আগের সংস্করণের সঙ্গে তুলনা করে সরানো ফিল্ড বা বদলানো টাইপ দেখুন।
তৃতীয় বিষয়ে টুলিং সমর্থন দরকার (যেমন openapi-diff বা json-schema-diff);
তা না থাকলে অন্তত স্ক্রিপ্ট দিয়ে required অ্যারে ও properties কি-সেটের পরিবর্তন তুলনা করুন।
৩. দ্রুত রেফারেন্স
| প্রশ্ন | সুপারিশ |
|---|---|
| রেসপন্স কাঠামো | {"data":..., "meta":...}, এররে HTTP স্টেটাস কোড |
| নামকরণ শৈলী | camelCase (ফ্রন্টএন্ড-প্রথম) বা snake_case (ডেটা-প্রথম), সাইটজুড়ে সামঞ্জস্যপূর্ণ |
| সময়ের ফরম্যাট | টাইম জোনসহ RFC 3339 স্ট্রিং, At-এ শেষ হওয়া ফিল্ড-নাম |
| null | মান নেই বোঝাতে null, অপ্রাসঙ্গিক ফিল্ড বাদ, PATCH-এ বাদ মানে "পরিবর্তন নয়" |
| বুলিয়ান নামকরণ | is/has/can প্রিফিক্স, নেতিবাচক নয়, 0/1 নয় |
| এনাম | স্ট্রিং, ছোট হাতের অক্ষর + আন্ডারস্কোর, Schema-তে enum যোগ |
| কনফিগ ফরম্যাট | প্রোগ্রামগত ভ্যালিডেশনে JSON, হাতে সম্পাদনায় TOML বা JSONC |
| ফিক্সচার | এক বেসলাইন + ন্যূনতম-ডিফ override, Schema-এর বিরুদ্ধে বৈধ |
| মার্জ কনফ্লিক্ট | ফরম্যাটিং একীভূত, কি সাজানো, ফাইল ভাগ |
| সংস্করণ সামঞ্জস্য | যোগ করুন, বদলাবেন না, মুছবেন না; সরানোর আগে ডেপ্রিকেটেড চিহ্নিত |