نحوه عملکرد زمینه درخواست (How Request Context Works)
در این بخش، نحوه عملکرد زمینه درخواست (Request Context) را بررسی میکنیم. این شامل مدیریت دادهها (Data Management)، انتشار سیگنال (Signal Propagation) و زمانبندی (Timing) میشود.
برای شروع، بیایید با مفاهیم پایه (Basic Concepts) زمینه درخواست آشنا شویم:
هر http.Request که میانافزار و هندلرهای ما پردازش میکنند، یک شیء context.Context در خود دارد که میتوانیم از آن برای ذخیره اطلاعات در طول عمر درخواست استفاده کنیم.
همانطور که قبلاً اشاره کردم، در یک برنامه وب یک مورد استفاده رایج برای این است که اطلاعات را بین قطعات میانافزار و هندلرهای دیگر خود منتقل کنید.
در مورد ما، میخواهیم از آن برای بررسی اینکه آیا یک کاربر احراز هویت شده است در برخی از میانافزارها استفاده کنیم، و اگر آنها احراز هویت شدهاند، این اطلاعات را برای همه میانافزارها و هندلرهای دیگر خود در دسترس قرار دهیم.
بیایید با کمی تئوری شروع کنیم و نحو کار با زمینه درخواست را توضیح دهیم. سپس، در فصل بعدی، دوباره کمی عملیتر خواهیم شد و نشان خواهیم داد که چگونه میتوان آن را به طور عملی در برنامه خود استفاده کرد.
نحو زمینه درخواست
کد پایه برای افزودن اطلاعات به زمینه یک درخواست به این صورت است:
// Where r is a *http.Request... ctx := r.Context() ctx = context.WithValue(ctx, "isAuthenticated", true) r = r.WithContext(ctx)
بیایید این را خط به خط بررسی کنیم.
- ابتدا، از روش
r.Context()برای بازیابی زمینه موجود از یک درخواست استفاده میکنیم و آن را به متغیرctxاختصاص میدهیم. - سپس از روش
context.WithValue()برای ایجاد یک نسخه جدید از زمینه موجود استفاده میکنیم که شامل کلید"isAuthenticated"و مقداری ازtrueاست. - سپس در نهایت از روش
r.WithContext()برای ایجاد یک نسخه از درخواست که شامل زمینه جدید ما است، استفاده میکنیم.
همچنین باید اشاره کنم که، برای وضوح، آن قطعه کد را کمی بیشتر از آنچه که نیاز بود، مفصل کردم. معمولاً به این صورت نوشته میشود:
ctx = context.WithValue(r.Context(), "isAuthenticated", true) r = r.WithContext(ctx)
پس اینگونه است که دادهها را به زمینه یک درخواست اضافه میکنید. اما چگونه میتوان آن را دوباره بازیابی کرد؟
نکته مهمی که باید توضیح دهم این است که، در پشت صحنه، مقادیر زمینه درخواست با نوع any ذخیره میشوند. و این بدان معناست که، پس از بازیابی آنها از زمینه، باید آنها را به نوع اصلی خود قبل از استفاده از آنها تبدیل کنید.
برای بازیابی یک مقدار باید از روش r.Context().Value() استفاده کنیم، به این صورت:
isAuthenticated, ok := r.Context().Value("isAuthenticated").(bool) if !ok { return errors.New("could not convert value to bool") }
اجتناب از برخورد کلیدها
در نمونههای کد بالا، من از رشته "isAuthenticated" به عنوان کلید برای ذخیره و بازیابی دادهها از زمینه یک درخواست استفاده کردهام. اما این توصیه نمیشود زیرا خطر این وجود دارد که بستههای شخص ثالث دیگری که توسط برنامه شما استفاده میشوند نیز بخواهند دادهها را با استفاده از کلید "isAuthenticated" ذخیره کنند — و این باعث برخورد نامگذاری میشود.
برای اجتناب از این، بهتر است نوع سفارشی خود را ایجاد کنید که میتوانید از آن برای کلیدهای زمینه خود استفاده کنید. با گسترش کد نمونه ما، بهتر است چیزی شبیه به این انجام دهید:
// Declare a custom "contextKey" type for your context keys. type contextKey string // Create a constant with the type contextKey that we can use. const isAuthenticatedContextKey = contextKey("isAuthenticated") ... // Set the value in the request context, using our isAuthenticatedContextKey // constant as the key. ctx := r.Context() ctx = context.WithValue(ctx, isAuthenticatedContextKey, true) r = r.WithContext(ctx) ... // Retrieve the value from the request context using our constant as the key. isAuthenticated, ok := r.Context().Value(isAuthenticatedContextKey).(bool) if !ok { return errors.New("could not convert value to bool") }
واژهنامه اصطلاحات فنی
| اصطلاح فارسی | معادل انگلیسی | توضیح |
|---|---|---|
| زمینه درخواست | Request Context | محیط اجرای درخواست |
| مدیریت دادهها | Data Management | کنترل دادههای درخواست |
| انتشار سیگنال | Signal Propagation | ارسال سیگنال در برنامه |
| زمانبندی | Timing | کنترل زمان اجرا |
| مفاهیم پایه | Basic Concepts | اصول اولیه |
| درخت زمینه | Context Tree | ساختار سلسله مراتبی زمینه |
| مقدار کلید | Key Value | داده ذخیره شده در زمینه |
| کانال لغو | Cancel Channel | کانال ارتباطی لغو عملیات |
| مهلت زمانی | Timeout | محدودیت زمان اجرا |
| همگامسازی | Synchronization | هماهنگی اجرای عملیات |