চমৎকার! আগের লেকচারগুলোতে আমরা Model, DbContext তৈরি করেছি এবং ডাটাবেজ সেটআপ সম্পন্ন করেছি। আজ আমরা আমাদের Web API-তে CRUD (Create, Read, Update, Delete) অপারেশন ইমপ্লিমেন্ট করতে যাচ্ছি। সবচেয়ে মজার বিষয় হলো, আজ আমরা নিজে থেকে সব কোড লিখবো না, বরং Entity Framework Core ব্যবহার করে অটোমেটিক Controller জেনারেট (Scaffolding) করা শিখবো।
চলুন শুরু করা যাক!
📝 Lecture Summary
ভবিষ্যতে দ্রুত রিভিশন দেওয়ার জন্য পুরো লেকচারের মূল বিষয়গুলো নিচে তালিকাভুক্ত করা হলো:
- Controller Scaffolding: Visual Studio-এর অটোমেটিক কোড জেনারেশন টুল ব্যবহার করে EF Core-এর সাহায্যে সম্পূর্ণ CRUD Controller তৈরি করা।
- GET Request: ডাটাবেজ থেকে সমস্ত ডেটা বা নির্দিষ্ট ID-এর ডেটা রিট্রিভ করা (Response: 200 OK)।
- POST Request: ডাটাবেজে নতুন ডেটা ইনসার্ট করা। Web API শুধুমাত্র JSON ডেটা গ্রহণ করে (Response: 201 Created)।
- PUT Request: বিদ্যমান ডেটা আপডেট করা। Route Parameter ID এবং Request Body-এর ID সেম হতে হবে (Response: 204 No Content)।
- DELETE Request: ডাটাবেজ থেকে ডেটা মুছে ফেলা। এর জন্য কোনো Request Body প্রয়োজন হয় না (Response: 204 No Content)।
- Testing with Postman: ব্রাউজার দিয়ে POST, PUT বা DELETE রিকোয়েস্ট পাঠানো যায় না, তাই API টেস্ট করার জন্য Postman ব্যবহার করা।
- SSL Verification: Postman-এ লোকালহোস্ট টেস্ট করার সময় “SSL verification” ডিজেবল করে নেওয়া।
🧠 Comprehensive Breakdown
নিচে লেকচারের প্রতিটি কনসেপ্ট বিস্তারিত এবং সহজভাবে ব্যাখ্যা করা হলো।
১. Controller Scaffolding (Importance: 9/10)
ভিডিওতে Visual Studio ব্যবহার করে API controller with actions, using Entity Framework অপশনটি সিলেক্ট করে একটি Controller জেনারেট করা হয়েছে।
Why? ম্যানুয়ালি GET, POST, PUT, DELETE-এর সব লজিক লিখতে অনেক সময় লাগে। Scaffolding আপনার Model (City) এবং DbContext (ApplicationDbContext) অ্যানালাইজ করে স্ট্যান্ডার্ড RESTful আর্কিটেকচার অনুযায়ী অটোমেটিক কোড জেনারেট করে দেয়।
💡 VS Code Alternative: আপনি যদি Visual Studio Code ব্যবহার করেন, তবে Terminal-এ নিচের কমান্ডটি রান করে হুবহু একই Controller জেনারেট করতে পারবেন:
dotnet aspnet-codegenerator controller -name CitiesController -async -api -m City -dc ApplicationDbContext -outDir Controllers
২. Testing APIs with Postman & SSL Issue (Importance: 10/10)
Web API-এর GET রিকোয়েস্ট ব্রাউজারে দেখা গেলেও POST, PUT, বা DELETE রিকোয়েস্ট ব্রাউজার থেকে সরাসরি করা যায় না। এগুলোর জন্য Postman (বা অনুরূপ কোনো API Client) ব্যবহার করতে হয়। লোকাল এনভায়রনমেন্টে HTTPS ব্যবহার করার কারণে Postman অনেক সময় SSL Error দিতে পারে। এটি সমাধানের জন্য Postman-এর সেটিংসে গিয়ে “Disable SSL verification” করে নিতে হয়।
৩. GET Operations: Retrieving Data (Importance: 10/10)
Scaffold হওয়া কন্ট্রোলারে দুটি GET মেথড থাকে।
- Get All:
/api/citiesএ হিট করলে এটি ডাটাবেজের সমস্ত শহরের লিস্ট একটি JSON Array হিসেবে রিটার্ন করে (Status 200 OK)। - Get by ID:
/api/cities/{id}এ হিট করলে এটি নির্দিষ্ট ID-এর শহরটিকে একটি সিঙ্গেল JSON Object হিসেবে রিটার্ন করে।
৪. POST Operation: Creating Data (Importance: 10/10)
নতুন রেকর্ড তৈরি করতে POST রিকোয়েস্ট ব্যবহার করা হয়।
- Why RAW JSON? Web API বাই-ডিফল্ট Query String বা Form Data প্রসেস করে না। তাই Postman-এ রিকোয়েস্ট বডি হিসেবে
rawঅপশন সিলেক্ট করে ড্রপডাউন থেকেJSONনির্বাচন করতে হয়। - Response: সফলভাবে ডেটা ইনসার্ট হলে RESTful স্ট্যান্ডার্ড অনুযায়ী সার্ভার
201 Createdস্ট্যাটাস কোড রিটার্ন করে।
💡 Pro Tip for GUID in Postman: > Visual Studio থেকে GUID কপি করার বদলে, Postman-এ Request Body-তে সরাসরি
{{$guid}}লিখলে Postman নিজেই প্রতিবার একটি নতুন GUID জেনারেট করে নেবে!
৫. PUT Operation: Updating Data (Importance: 10/10)
বিদ্যমান ডেটা আপডেট করতে PUT রিকোয়েস্ট ব্যবহার করা হয়।
- Crucial Rule: PUT রিকোয়েস্টের URL-এ যে ID থাকবে (যেমন:
/api/cities/id), Request Body-এর JSON-এর ভেতরের ID ঠিক একই হতে হবে। যদি না মেলে, সার্ভার400 Bad Requestদেবে। - Method Not Allowed (405): যদি আপনি URL-এ ID না দিয়ে শুধু
/api/citiesএ PUT রিকোয়েস্ট পাঠান, সার্ভার405 Method Not Allowedরিটার্ন করবে, কারণ ID ছাড়া আপডেট করার কোনো মেথড কন্ট্রোলারে নেই। - Response: সফলভাবে আপডেট হলে সার্ভার
204 No Contentরিটার্ন করে। এর মানে হলো অপারেশন সাকসেসফুল, কিন্তু দেখানোর মতো নতুন কোনো ডেটা নেই।
৬. DELETE Operation: Removing Data (Importance: 9/10)
ডেটা ডিলিট করার জন্য DELETE রিকোয়েস্ট পাঠানো হয় URL-এর সাথে ID যুক্ত করে (যেমন: /api/cities/id)।
- No Body Needed: GET-এর মতোই DELETE রিকোয়েস্টের কোনো Body থাকে না।
- Response: সফল ডিলিটের পর
204 No Contentস্ট্যাটাস কোড আসে। এরপর ওই একই ID-তে GET রিকোয়েস্ট পাঠালে সার্ভার404 Not Foundরিটার্ন করবে, কারণ রেকর্ডটি আর ডাটাবেজে নেই।
💻 Code Implementation (.NET 10 Updated Smart Approach)
ভিডিওতে দেখানো Controller বেসড আর্কিটেকচারটি এখনো দারুণভাবে কাজ করে। কিন্তু .NET 10-এ ছোট বা মাঝারি প্রজেক্টের জন্য Minimal API ব্যবহার করাটা অনেক বেশি জনপ্রিয় এবং ফাস্ট। নিচে একই CRUD অপারেশনগুলো Minimal API ব্যবহার করে Program.cs ফাইলে কীভাবে লেখা যায় তার উদাহরণ দেওয়া হলো:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(builder.Configuration.GetConnectionString("Default")));
var app = builder.Build();
// 1. GET All Cities
app.MapGet("/api/cities", async (ApplicationDbContext db) =>
await db.Cities.ToListAsync());
// 2. GET City by ID
app.MapGet("/api/cities/{id}", async (Guid id, ApplicationDbContext db) =>
await db.Cities.FindAsync(id) is City city ? Results.Ok(city) : Results.NotFound());
// 3. POST (Create)
app.MapPost("/api/cities", async (City city, ApplicationDbContext db) =>
{
db.Cities.Add(city);
await db.SaveChangesAsync();
return Results.Created($"/api/cities/{city.CityID}", city);
});
// 4. PUT (Update)
app.MapPut("/api/cities/{id}", async (Guid id, City updatedCity, ApplicationDbContext db) =>
{
if (id != updatedCity.CityID) return Results.BadRequest();
db.Entry(updatedCity).State = EntityState.Modified;
await db.SaveChangesAsync();
return Results.NoContent();
});
// 5. DELETE
app.MapDelete("/api/cities/{id}", async (Guid id, ApplicationDbContext db) =>
{
var city = await db.Cities.FindAsync(id);
if (city == null) return Results.NotFound();
db.Cities.Remove(city);
await db.SaveChangesAsync();
return Results.NoContent();
});
app.Run();
🏆 Best Practices for Web API CRUD
- Use DTOs (Data Transfer Objects): কখনোই ডাটাবেজ Model (
Cityক্লাস) সরাসরি ক্লায়েন্টের কাছে রিটার্ন বা রিসিভ করবেন না। এর বদলেCityDTOক্লাস তৈরি করুন। এতে ডাটাবেজের সেনসিটিভ তথ্য (যেমন: Internal ID বা Password) সুরক্ষিত থাকে। - Async/Await is Mandatory: ডাটাবেজ অপারেশনগুলো সবসময় Asynchronous হতে হবে (যেমন:
ToListAsync(),SaveChangesAsync())। এতে সার্ভারের মেইন থ্রেড ব্লক হয় না এবং একসাথে অনেক ইউজার হ্যান্ডেল করা যায়। - Return Proper Status Codes: ঠিক যে কাজের জন্য যে স্ট্যাটাস কোড নির্ধারিত, সেটিই পাঠাবেন।
- ডেটা পেলে:
200 OK - নতুন কিছু তৈরি হলে:
201 Created - আপডেট বা ডিলিট হলে:
204 No Content - ডেটা না পেলে:
404 Not Found - ক্লায়েন্ট ভুল ডেটা পাঠালে:
400 Bad Request