হ্যালো! আমি আপনার “Simple Coding Tutor”। আপনার দেওয়া লেকচার ট্র্যান্সক্রিপ্টটি ASP.NET Core-এ HttpClient (Part 1) (লেকচার ১৫৯) নিয়ে আলোচনা করেছে। এটি একটি অত্যন্ত গুরুত্বপূর্ণ টপিক, কারণ এর মাধ্যমে আমাদের অ্যাপ অন্য সার্ভারের সাথে যোগাযোগ করতে পারে। চলুন, পুরো বিষয়টি বিস্তারিতভাবে শিখে নেওয়া যাক।
📝 সারসংক্ষেপ (Quick Summary for Revision)
ভবিষ্যতে দ্রুত রিভিশন দেওয়ার জন্য মূল পয়েন্টগুলো নিচে লিস্ট করা হলো:
- উদ্দেশ্য: ASP.NET Core অ্যাপ্লিকেশনের সার্ভার সাইড থেকে অন্য কোনো এক্সটার্নাল বা থার্ড-পার্টি ওয়েব সার্ভিস (যেমন: Twitter, Weather API, Stock Market API)-এ HTTP Request (GET, POST, PUT, DELETE) পাঠানোর জন্য
HttpClientক্লাস ব্যবহার করা হয়। - HttpClientFactory: সরাসরি
new HttpClient()তৈরি করার বদলেIHttpClientFactoryব্যবহার করা বেস্ট প্র্যাকটিস। এটি কানেকশন ক্লোজিং এবং রিসোর্স ম্যানেজমেন্ট স্বয়ংক্রিয়ভাবে হ্যান্ডেল করে। - Setup:
Program.csফাইলেbuilder.Services.AddHttpClient();যোগ করতে হয়। - Request Object:
HttpRequestMessageক্লাসের মাধ্যমে টার্গেট URL, HTTP Method (যেমন: GET) এবং Headers সেট করা হয়। - Sending Request:
_httpClient.SendAsync(request)মেথড ব্যবহার করে রিকোয়েস্ট পাঠানো হয় এবংHttpResponseMessageহিসেবে রেসপন্স গ্রহণ করা হয়। - Using Block:
HttpClient-এর ইনস্ট্যান্সকে মেমোরি লিক থেকে বাঁচাতেusingব্লকের ভেতর রাখতে হয়, যেন কাজ শেষে নিজে নিজেই ডিসপোজ (dispose) হয়ে যায়।
🧠 Comprehensive Breakdown
১. HttpClient কী এবং কেন ব্যবহার করা হয়? (The “Why”) [Priority: 10/10]
সাধারণত ক্লায়েন্ট (ব্রাউজার) আপনার ASP.NET Core সার্ভারে রিকোয়েস্ট পাঠায়। কিন্তু অনেক সময় আপনার সার্ভারকেও অন্য কোনো সার্ভারের (যেমন: Finnhub Stock API, Payment Gateway) কাছে রিকোয়েস্ট পাঠাতে হয়।
এই অবস্থায় আপনার ASP.NET Core সার্ভার নিজে একটি “Client” হিসেবে কাজ করে। এই কাজটি করার জন্যই System.Net.Http নেমস্পেসের HttpClient ক্লাসটি ব্যবহার করা হয়। এটি অন্য সার্ভারে রিকোয়েস্ট পাঠিয়ে ডেটা (যেমন: JSON রেসপন্স) নিয়ে আসতে পারে।
২. প্রজেক্ট সেটআপ এবং UI তৈরি [Priority: 3/10]
লেকচারার প্রথমে একটি বেসিক Stocks App তৈরি করেছেন।
Program.cs-এ MVC এবং Static Files এনাবল করা হয়েছে।Controllers/HomeController.csতৈরি করা হয়েছে।Views/Shared/_Layout.cshtmlতৈরি করে Font Awesome আইকন এবং কিছু কাস্টম CSS ক্লাস যুক্ত করা হয়েছে।_ViewStart.cshtmlতৈরি করে ডিফল্ট লেআউট সেট করা হয়েছে।- এটি মূলত প্রজেক্টের বেসলাইন সেটআপ, HttpClient-এর মূল লজিকের সাথে এর সরাসরি সম্পর্ক নেই।
৩. HttpClient সার্ভিস রেজিস্টার করা [Priority: 10/10]
ডিপেন্ডেন্সি ইনজেকশন (DI) ব্যবহার করে HttpClient বা IHttpClientFactory পাওয়ার জন্য প্রথমে এটিকে Program.cs ফাইলে রেজিস্টার করতে হয়।
Code Implementation (Program.cs):
var builder = WebApplication.CreateBuilder(args);
// Controllers with Views যোগ করা
builder.Services.AddControllersWithViews();
// HttpClient Service রেজিস্টার করা (Critical Step)
builder.Services.AddHttpClient();
var app = builder.Build();
app.UseStaticFiles();
app.UseRouting();
app.MapControllers();
app.Run();
৪. IHttpClientFactory vs HttpClient [Priority: 10/10]
লেকচারার একটি অত্যন্ত গুরুত্বপূর্ণ বিষয় তুলে ধরেছেন: সরাসরি HttpClient ব্যবহার না করে IHttpClientFactory কেন ব্যবহার করব?
- যদি আপনি সরাসরি
new HttpClient()তৈরি করেন, তবে রিকোয়েস্ট শেষ হওয়ার পর ম্যানুয়ালি সার্ভার কানেকশন ক্লোজ করতে হয়। তা না করলে মেমোরি লিক বা Socket Exhaustion সমস্যা হতে পারে। IHttpClientFactoryএই সমস্যা সমাধান করে। এটি একটি ফ্যাক্টরি ইন্টারফেস, যা আপনার জন্যHttpClient-এর একটি ইনস্ট্যান্স তৈরি করে দেয় এবং কাজ শেষ হলে কানেকশন ডিসপোজ (Dispose) করার দায়িত্ব নিজেই নেয়।
৫. Service Class তৈরি এবং Request পাঠানো [Priority: 10/10]
এবার আমরা একটি ডামি সার্ভিস ক্লাস তৈরি করব, যেখানে IHttpClientFactory ইনজেক্ট করে একটি এক্সটার্নাল API-তে রিকোয়েস্ট পাঠানো হবে।
Code Implementation (MyService.cs):
using System.Net.Http;
using System.Threading.Tasks;
public class MyService
{
private readonly IHttpClientFactory _httpClientFactory;
// 1. Constructor Injection
public MyService(IHttpClientFactory httpClientFactory)
{
_httpClientFactory = httpClientFactory;
}
// 2. Async Method for HTTP Request
public async Task GetExternalDataAsync()
{
// 3. IHttpClientFactory ব্যবহার করে HttpClient-এর ইনস্ট্যান্স তৈরি
// using ব্লক নিশ্চিত করে যে কাজ শেষে এটি Dispose হবে
using (HttpClient httpClient = _httpClientFactory.CreateClient())
{
// 4. Request Object তৈরি করা
HttpRequestMessage request = new HttpRequestMessage()
{
// টার্গেট URL (Uri অবজেক্ট হিসেবে দিতে হয়)
RequestUri = new Uri("https://finnhub.io/api/v1/some-endpoint"),
// HTTP Method সেট করা (GET, POST, PUT, etc.)
Method = HttpMethod.Get
};
// Optional: Header যোগ করা (যেমন API Key)
// request.Headers.Add("X-Finnhub-Token", "your_api_key_here");
// 5. রিকোয়েস্ট পাঠানো এবং রেসপন্স রিসিভ করা
HttpResponseMessage response = await httpClient.SendAsync(request);
// 6. Response চেক করা (success status code 200-299 এর মধ্যে কিনা)
if (response.IsSuccessStatusCode)
{
// Response Body রিড করা (পরবর্তী লেকচারে বিস্তারিত আসবে)
string responseBody = await response.Content.ReadAsStringAsync();
}
}
}
}
💡 Best Practices & .NET 10 Context
.NET Core থেকে শুরু করে .NET 10 পর্যন্ত IHttpClientFactory ব্যবহার করাই ইন্ডাস্ট্রি স্ট্যান্ডার্ড। তবে .NET 10-এ এটি আরও অপ্টিমাইজড হয়েছে। নিচে কিছু Best Practices দেওয়া হলো:
- Typed Clients (Highly Recommended):
শুধু
IHttpClientFactoryব্যবহার না করে Typed Client ব্যবহার করা বেস্ট প্র্যাকটিস। এতে কোড আরও ক্লিন হয় এবং সরাসরি সার্ভিস ক্লাসেইHttpClientকনফিগার করা যায়। Example (Typed Client in .NET 10):
// Program.cs এ Typed Client রেজিস্টার করা
builder.Services.AddHttpClient<MyService>(client =>
{
client.BaseAddress = new Uri("https://finnhub.io/");
client.DefaultRequestHeaders.Add("Accept", "application/json");
});
// Service Class (আর IHttpClientFactory লাগবে না)
public class MyService
{
private readonly HttpClient _httpClient;
// সরাসরি HttpClient ইনজেক্ট হবে
public MyService(HttpClient httpClient)
{
_httpClient = httpClient;
}
public async Task GetDataAsync()
{
// RequestUri বা Method আলাদা করে ডিফাইন করার দরকার নেই
var response = await _httpClient.GetAsync("api/v1/some-endpoint");
}
}
- Resilience with Polly:
এক্সটার্নাল API মাঝে মাঝে ডাউন থাকতে পারে। তাই
HttpClient-এর সাথে Polly লাইব্রেরি ব্যবহার করে Retry Logic (যেমন: ফেইল করলে ৩ বার আবার চেষ্টা করা) যুক্ত করা একটি বেস্ট প্র্যাকটিস (যা পরবর্তী অ্যাডভান্সড লেকচারগুলোতে আসতে পারে)।