> For the complete documentation index, see [llms.txt](https://mominur.gitbook.io/mominur-notes/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://mominur.gitbook.io/mominur-notes/system-design/api/the-hidden-api-bug-no-one-talks-about.md).

# The hidden API bug no one talks about

ভাবুন, আপনি কিছু **REST API** বানিয়েছেন — যেখানে প্রতিটি ইউজারের একাধিক রেকর্ড যেমন *নোট, অর্ডার, ইনভয়েস* বা *টাস্ক* নিখুঁতভাবে ম্যানেজ হচ্ছে। ইউজার লগইন করছে, নিজের ডাটা দেখছে, এডিট করছে, ডিলিট করছে — সবই পারফেক্ট মনে হচ্ছে।

কিন্তু হঠাৎ একদিন দেখলেন , একজন ইউজার তার **নিজের ডাটার মধ্যেই গণ্ডগোল করে ফেলছে।**

সে `Note #1` ফেচ করেছে আপডেটের জন্য, কিন্তু আপডেট করার সময় `Note #3`-এর ডাটা পাঠিয়েছে —\
অথবা ডিলিট করতে গিয়ে `Note #1` নয়, ভুলবশত `Note #3` মুছে ফেলেছে।

সবচেয়ে ভয়ানক ব্যাপার? দুটোই তার নিজের রেকর্ড, এবং সে সম্পূর্ণভাবে **authorized user**!

এটাই হলো এক ধরণের **Broken Object-Level Integrity** সমস্যা —\
যেখানে ইউজার অন্যের না হলেও, **নিজেরই ভুল রেকর্ড আপডেট বা ডিলিট করে ফেলতে পারে।**

***

### সমস্যা আসলে কোথায়?

REST API-তে সাধারণত Update অপারেশন হয় এমনভাবে:

```
GET /notes/1
→ { "id": 1, "title": "Old Note" }

PUT /notes/1
→ { "id": 3, "title": "Updated Note!" }  ❌
```

ক্লায়েন্ট ফেচ করেছে Note #1\
কিন্তু আপডেট রিকোয়েস্টে পাঠিয়ে দিয়েছে `id=3` — অর্থাৎ **অন্য নিজের রেকর্ডের ID**।

সার্ভার যদি শুধু `id` বিশ্বাস করে,\
তাহলে সে ভুল রেকর্ড আপডেট করে ফেলবে।\
ফলাফল? ডাটা inconsistency, confusion, এবং ভবিষ্যতের debug nightmare

***

### কীভাবে এই সমস্যা সমাধান করা যায়

এই সমস্যা সমাধান করতে হলে আমাদের নিশ্চিত করতে হবে — ইউজার যে রেকর্ডটি **Fetch করেছে**, সে আপডেট বা ডিলিটের সময় **ঠিক সেই একই রেকর্ডের উপরই কাজ করছে।**

অর্থাৎ সার্ভারকে বুঝতে হবে,

> এটাই সেই রেকর্ড, যেটি ক্লায়েন্ট আসলেই দেখেছিল বা এডিট করতে চেয়েছিল।

এই ভ্যালিডেশন করার জন্য কয়েকটি কার্যকর **approach** ব্যবহার করা যায়&#x20;

***

### Using `writeToken`

প্রতিটি রেকর্ডের সাথে একটি ইউনিক `writeToken` সংরক্ষণ করুন। যখন ইউজার রেকর্ড Fetch করবে, তখন সেই টোকেন রেসপন্সে পাঠিয়ে দিন। পরে ইউজার আপডেট বা ডিলিট করার সময় একই টোকেনটি রিকোয়েস্টে পাঠাবে।

```python
# Example:
GET /notes/1
→ { "id": 1, "title": "Note", "writeToken": "aB9xL2q" }

PUT /notes/1
→ { "id": 1, "title": "Updated Note", "writeToken": "aB9xL2q" }
```

সার্ভার যখন আপডেট বা ডিলিট রিকোয়েস্ট পায়, তখন সে প্রথমে যাচাই করে — **যে `writeToken` ক্লায়েন্ট পাঠিয়েছে**, সেটি কি **রেকর্ডে সংরক্ষিত `writeToken`-এর সঙ্গে মিলে যাচ্ছে**?

যদি দুইটা এক না হয়, তাহলে সার্ভার বুঝে নেয় — ক্লায়েন্ট আসলে অন্য কোনো রেকর্ডের টোকেন পাঠিয়েছে, অথবা টোকেনটি পরিবর্তন হয়েছে বা মেয়াদোত্তীর্ণ।

সেই ক্ষেত্রে সার্ভার সঙ্গে সঙ্গেই রিকোয়েস্টটি বাতিল করে দেয় এবং বলে —

> তুমি যে রেকর্ডটি আপডেট করতে চাও, তার টোকেন সঠিক নয়।

এই যাচাইয়ের মাধ্যমেই সার্ভার নিশ্চিত করে যে ইউজার কেবলমাত্র সেই রেকর্ডেই পরিবর্তন করতে পারবে\
যেটি সে সত্যিকার অর্থে Fetch করেছিল। ফলে ইউজার ভুল করে অন্য রেকর্ডের ডাটা আপডেট করতে পারবে না।

***

### Combine `id` + `version_number`

রেকর্ডের প্রতিবার পরিবর্তনের পর একটি **`version_number`** বাড়তে থাকবে। ক্লায়েন্ট যখন রেকর্ড Fetch করবে, তখন সে version ও পাবে। আপডেটের সময় সার্ভার যাচাই করবে — ক্লায়েন্টের পাঠানো version ও id ডাটাবেসের version ,id এক কিনা।

এতে নিশ্চিত হয়, রেকর্ডের **consistency** ঠিক আছে, এবং পুরোনো বা ভুল ডাটা দিয়ে আপডেট করা হচ্ছে না।

***

#### Other Approaches

* **`recordHash` বা digital signature** ব্যবহার করা যায়, যা রেকর্ডের state fingerprint হিসেবে কাজ করবে।
* **`updateNonce`** (one-time-use token) ব্যবহার করলে replay attack থেকেও সুরক্ষা পাওয়া যায়।
* **Server-side locking** ব্যবহার করা যেতে পারে critical data-এর জন্য (যেমন finance বা invoice)।

***

### কেন এটা দরকার?

এই সমস্যা শুধু security না — এটা **data integrity** ইস্যু। ইউজার তার নিজের রেকর্ডও যদি ভুল আইডি দিয়ে আপডেট করে ফেলে, তাহলে রিপোর্ট, হিসাব বা অ্যানালিটিক্সে সব কিছু ভুল হয়ে যেতে পারে।

**Write Token / Version Validation** নিশ্চিত করে যে —

* প্রতিটি Edit রিকোয়েস্ট traceable&#x20;
* ভুল রেকর্ডে accidental update বন্ধ&#x20;
* concurrent editing এর সময় conflict detect করা যায়&#x20;

***

REST API মানে শুধু CRUD না — বরং প্রতিটি request-এর Intent, server-side প্রমাণিত হতে হবে। একজন ইউজার ইচ্ছাকৃতভাবে বা ভুল করে নিজের অন্য রেকর্ড আপডেট করতে না পারে — এই সূক্ষ্ম কিন্তু গুরুত্বপূর্ণ চেকটাই mature backend architecture-এর পরিচয়।
