APIs - আর্কিটেকচার এবং সিকিউরিটি
API (Application Programming Interface) হলো ইন্টারনেটের যোগাযোগ ব্যবস্থা। একজন জুনিয়র ডেভেলপার API বানায় ডাটা পাস করার জন্য। একজন Senior Developer API ডিজাইন করে সিকিউরিটি, ভার্সন কন্ট্রোল এবং ফিউচার স্কেলেবিলিটি মাথায় রেখে।
এই অধ্যায়ে আমরা কোনো ফ্রেমওয়ার্কের জাদু ছাড়াই Raw পিএইচপি দিয়ে একটি ইন্ডাস্ট্রি স্ট্যান্ডার্ড API আর্কিটেকচার তৈরি করব।
১০.১ Raw PHP REST API — ফ্রেমওয়ার্ক ছাড়া জীবন
ফ্রেমওয়ার্ক (Laravel/Symfony) অনেক কিছু লুকিয়ে রাখে। নিজে হাতে আর্কিটেকচার বানালে আপনি HTTP লাইফসাইকেল পুরোপুরি বুঝতে পারবেন।
📁 ফোল্ডার স্ট্রাকচার (The Skeleton)
public/
└── index.php (Single Entry Point)
src/
├── Core/ (Router, Request, Response)
├── Controllers/(Request handle করে)
├── Services/ (Business Logic থাকে)
└── Repositories/(Database Query থাকে)
🚪 এন্ট্রি পয়েন্ট (index.php)
সব রিকোয়েস্ট এই ফাইলেই আসবে।
header("Content-Type: application/json; charset=UTF-8");
header("Access-Control-Allow-Methods: GET, POST, PUT, DELETE");
// অটোলোডার লোড
require "../vendor/autoload.php";
$uri = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
$method = $_SERVER['REQUEST_METHOD'];
// রাউটার হ্যান্ডেল করছে
$router = new AppCoreRouter();
$router->dispatch($method, $uri);
💡 Senior Insight: এখানে header() ফাংশনগুলো খুব গুরুত্বপূর্ণ। রেসপন্স টাইপ JSON বলে না দিলে ফ্রন্টএন্ড কনফিউজড হয়ে যাবে।
১০.২ JWT — আধুনিক অথেনটিকেশন (Deep Dive)
JWT (JSON Web Token) হলো স্টেটলেস অথেনটিকেশন। অর্থাৎ, সার্ভার সেশন মনে রাখে না, টোকেন নিজেই নিজের পরিচয় বহন করে।
🔐 স্ট্রাকচার (Header.Payload.Signature)
- Header: অ্যালগরিদম কী? (HS256)
- Payload: ডাটা (User ID, Expiry, Role)
- Signature: সিক্রেট চাবি দিয়ে এনক্রিপ্ট করা অংশ
⚠️ সিকিউরিটি চেকলিস্ট (Must Follow):
- No Sensitive Data: পেলোডে (Payload) কখনোই পাসওয়ার্ড রাখবেন না। কারণ এটা Base64 ডিকোড করলেই দেখা যায়
- Expiry (exp): টোকেনের মেয়াদ অবশ্যই থাকতে হবে
- Storage: লোকাল স্টোরেজে (localStorage) টোকেন রাখা বিপজ্জনক (XSS অ্যাটাক হতে পারে)
✅ Best Practice: httpOnly কুকিতে টোকেন রাখা, যা জাভাস্ক্রিপ্ট দিয়ে এক্সেস করা যায় না।
১০.৩ অ্যাক্সেস টোকেন বনাম রিফ্রেশ টোকেন (The Flow)
যদি অ্যাক্সেস টোকেনের মেয়াদ ১ বছর দেন, আর টোকেন চুরি হয়ে যায়, হ্যাকার ১ বছর আপনার অ্যাকাউন্ট চালাবে। তাই অ্যাক্সেস টোকেনের মেয়াদ কম রাখা হয়।
🎫 Access Token
মেয়াদ কম (১৫ মিনিট)। প্রতিটি API রিকোয়েস্টে এটি হেডারে পাঠানো হয়।
🔄 Refresh Token
মেয়াদ বেশি (৭-৩০ দিন)। এটি নিরাপদ কুকিতে থাকে।
🔄 Workflow:
- ক্লায়েন্ট লগিন করল → সার্ভার Access + Refresh টোকেন দিল
- Access Token দিয়ে ক্লায়েন্ট ডাটা আনছে
- ১৫ মিনিট পর Access Token মেয়াদোত্তীর্ণ হলো (401 Error)
- ক্লায়েন্ট তখন Refresh Token দিয়ে
/api/refresh-tokenএ হিট করে - সার্ভার চেক করে রিফ্রেশ টোকেন ভ্যালিড কি না। ভ্যালিড হলে নতুন Access Token দেয়
১০.৪ রেট লিমিটিং (সার্ভার প্রটেকশন)
API পাবলিক হলে যে কেউ স্ক্রিপ্ট চালিয়ে সার্ভার ডাউন করে দিতে পারে (Brute Force / DDoS)।
📦 Redis দিয়ে রেট লিমিট লজিক:
$ip = $_SERVER['REMOTE_ADDR'];
$key = "rate_limit:" . $ip;
$current = $redis->incr($key); // কাউন্টার ১ বাড়াও
if ($current === 1) {
$redis->expire($key, 60); // প্রথম রিকোয়েস্ট হলে ৬০ সেকেন্ড মেয়াদ দাও
}
if ($current > 100) {
http_response_code(429); // Too Many Requests
exit(json_encode(["error" => "Slow down! Limit exceeded."]));
}
এটি অত্যন্ত ফাস্ট কারণ Redis মেমোরিতে কাজ করে।
১০.৫ CORS — ক্রস অরিজিন পলিসি
জুনিয়রদের সবচেয়ে বড় ভয়ের নাম CORS। এটি সার্ভারের দোষ নয়, ব্রাউজারের সিকিউরিটি ফিচার।
⚙️ কনফিগারেশন:
// কোন ডোমেইন থেকে রিকোয়েস্ট আসবে?
header("Access-Control-Allow-Origin: https://my-frontend.com");
// কী কী মেথড এলাউড?
header("Access-Control-Allow-Methods: GET, POST, OPTIONS");
// হেডার এবং ক্রেডেনশিয়ালস
header("Access-Control-Allow-Headers: Content-Type, Authorization");
header("Access-Control-Allow-Credentials: true");
⚠️ সিনিয়রের সতর্কতা:
কখনোই Access-Control-Allow-Origin: * দেবেন না যদি আপনি কুকি বা অথেনটিকেশন ব্যবহার করেন। সিকিউরিটি রিস্ক এড়াতে নির্দিষ্ট ডোমেইন উল্লেখ করুন।
১০.৬ ফিল্টারিং এবং পেজিনেশন
API ডিজাইন করার সময় মনে রাখবেন—ইউজার সব ডাটা একসাথে চায় না।
🎯 ফিল্টারিং প্যাটার্ন:
URL: /users?role=admin&active=1
$query = "SELECT * FROM users WHERE 1=1";
$params = [];
if (!empty($_GET['role'])) {
$query .= " AND role = :role";
$params['role'] = $_GET['role'];
}
// ... execute with params
📄 কার্সর বেসড পেজিনেশন (Cursor Based):
আমরা আগের অধ্যায়ে (চ্যাপ্টার ৯) দেখেছি OFFSET স্লো। API-তে আমরা cursor ব্যবহার করব।
URL: /users?cursor=LAST_SEEN_ID
SELECT * FROM users WHERE id > :cursor LIMIT 20
এটি যেকোনো সাইজের ডাটাবেসে মিলি-সেকেন্ডে রেসপন্স দেয়।
১০.৭ ভার্সনিং (ভবিষ্যতের প্রস্তুতি)
আপনার অ্যাপ আপডেট হবে, কিন্তু পুরনো অ্যাপ ইউজারদের জন্য API বন্ধ করা যাবে না। তাই ভার্সনিং জরুরি।
🏷️ Industry Standard (URL Path):
GET /api/v1/users (Old logic)
GET /api/v2/users (New logic)
এতে ফ্রন্টএন্ড ডেভেলপাররা সময় পায় মাইগ্রেট করার জন্য এবং সিস্টেম ক্র্যাশ করে না।
১০.৮ স্ট্যান্ডার্ড রেসপন্স ফরম্যাট
API রেসপন্স যদি একেক সময় একেক রকম হয়, ফ্রন্টএন্ড ডেভেলপার আপনাকে অভিশাপ দেবে। একটি ফিক্সড স্ট্রাকচার মেনে চলুন।
✅ সফল রেসপন্স (JSend Style):
{
"status": "success",
"data": {
"user": { "id": 1, "name": "Shagor" }
}
}
❌ ব্যর্থ রেসপন্স:
{
"status": "error",
"message": "Invalid credentials",
"code": 401,
"errors": {
"email": "Email format is wrong"
}
}
১০.৯ এন্টারপ্রাইজ প্রজেক্ট স্ট্রাকচার
সবকিছু Controllers ফোল্ডারে লিখবেন না। Separation of Concerns মেনে চলুন।
🏗️ লেয়ার্ড আর্কিটেকচার:
Route → AuthMiddleware → UserController → UserService → UserRepository → Database
- Route: ট্রাফিক রিসিভ করে কন্ট্রোলারে পাঠায়
- Middleware: অথেনটিকেশন এবং রেট লিমিট চেক করে
- Controller: রিকোয়েস্ট ভ্যালিডেট করে এবং সার্ভিস কল করে
- Service: মূল বিজনেস লজিক (যেমন: ট্যাক্স ক্যালকুলেশন, ইমেইল পাঠানো) এখানে থাকে
- Repository: ডাটাবেস কুয়েরি হ্যান্ডেল করে
🎯 Senior Developer Interview Questions (Chapter 10)
Q: Access Token এবং Refresh Token এর মেকানিজম কেন ব্যবহার করা হয়? শুধু Access Token থাকলে সমস্যা কী?
সিকিউরিটি এবং ইউজার এক্সপেরিয়েন্স ব্যালেন্স করার জন্য। শুধু লং-টার্ম Access Token দিলে চুরি হলে বিপদ, আর শর্ট-টার্ম দিলে ইউজারকে বারবার লগিন করতে হবে। রিফ্রেশ টোকেন এই সমস্যার সমাধান করে।
Q: CORS এরর ব্রাউজারে কেন দেখায়? সার্ভার সাইডে এটি কীভাবে ফিক্স করবেন?
ব্রাউজার এক ডোমেইন থেকে অন্য ডোমেইনে রিকোয়েস্ট ব্লক করে নিরাপত্তা দিতে। সার্ভারে Access-Control-Allow-Origin হেডার সেট করে ব্রাউজারকে জানাতে হয় যে এই রিকোয়েস্টটি নিরাপদ।
Q: বড় ডাটাবেসের জন্য API পেজিনেশনে OFFSET ব্যবহার না করে কী ব্যবহার করবেন?
Cursor-based বা ID-based পেজিনেশন ব্যবহার করব, যা অনেক ফাস্ট এবং ডাটা স্কিপ করার জন্য স্ক্যান করতে হয় না।
Q: JWT টোকেন কোথায় স্টোর করা সবচেয়ে নিরাপদ?
httpOnly এবং Secure ফ্ল্যাগসহ কুকিতে (Cookie)। এটি জাভাস্ক্রিপ্ট দিয়ে এক্সেস করা যায় না, তাই XSS অ্যাটাক থেকে নিরাপদ।
🎯 অধ্যায় ১০ এর সারাংশ (Summary)
এই অধ্যায়ে আমরা শিখলাম:
- ✓Raw PHP API: Single Entry Point, Router, JSON Headers
- ✓JWT Authentication: Header.Payload.Signature structure
- ✓Access/Refresh Token: short-lived + long-lived token pattern
- ✓Rate Limiting: Redis-based IP throttling (429 response)
- ✓CORS: Access-Control-Allow-Origin headers, never use wildcard (*) with auth
- ✓Cursor Pagination: WHERE id > cursor LIMIT 20 (O(1) performance)
- ✓Versioning: /api/v1/, /api/v2/ URL pattern
- ✓JSend Response: status + data/message/errors structure
- ✓Layered Architecture: Route → Middleware → Controller → Service → Repository
✨ এখন আপনি জানেন কীভাবে একটি স্কেলেবল, সিকিউর এবং প্রফেশনাল API সিস্টেম ডিজাইন করতে হয়।
পরবর্তী অধ্যায়: Part 11 — Testing (PHPUnit, Pest) — যেখানে Unit Testing, Mocking এবং Test Coverage নিয়ে আলোচনা হবে।
🚀 PHP Journey Continues...