tgoop.com/ninja_learn_ir/770
Create:
Last Update:
Last Update:
سیستم مدیریت وابستگی در FastAPI
یکی از بهترین ویژگی های FastAPI، سیستم مدیریت وابستگی(Dependnecy Injection) اون هست، این سیستم باعث میشه کد ما تمیز تر، تست پذیر تر و قابل توسعه تر بشه.
بهتره برای درک بهتر این پست درمورد Dependency Injectionرو مطالعه کنید تا با پایه و اساس این مبحث آشنا بشین.
Depends چیه؟
این کلاس توی FastAPI، برای مدیریت وابستگی ها استفاده میشه. به زبان ساده Depends یه راهه که بتونیم بک تابع یا آبجکت رو به صورت خودکار به فانکشن های دیگه تزریق کنیم بدون اینکه دستی اونارو صدا بزنیم یا بخونیم.
با یه مثال ساده شروع میکنیم:
from fastapi import FastAPI, Depends
app = FastAPI()
def get_db():
db = "Database Connection"
try:
yield db
finally:
print("Closing DB connection")
@app.get("/items/")
def read_items(db = Depends(get_db)):
return {"db_connection": db}
اینجا
read_items
خودش مستقیم سشن دیتابیس رو نمیسازه، فقط میگه: من به یه سشن دیتابیس نیاز دارم.FastAPI به صورت خودکار
get_db
رو صدا میزنه و نتیجه رو به db میده.چرا این سیستم خوبه؟
وابستگی ها مدیریت شده و قابل کنترل میشن
کد تست پذیر تر میشه
ساختار پروژه ماژولار میشه
لاجیک لایه های مختلف جدا میشه و تغییرات ساده تر میشن
اگه ازش استفاده نکنیم چی؟
خب با استفاده نکردن از این ویژگی یه کمک بزرگ رو از دست میدین. به طور مثال اگه وابستگی ها تو در تو باشن شما میتونید فقط با همین ویژگی کلی به تمیزی کدتون کمک کنید.
from fastapi import Header, HTTPException, APIRouter, Depends
router = APIRouter()
def get_token(token: str = Header(...)):
return token
def get_current_user(token: str = Depends(get_token)):
user = {"username": "abolfazl", "role": "admin"}
return user
def require_admin(user: dict = Depends(get_current_user)):
if user["role"] != "admin":
raise HTTPException(status_code=403, detail="Not authorized")
return user
def list_users_service():
return [{"username": "a"}, {"username": "b"}]
@router.get("/users")
def list_users(admin_user: dict = Depends(require_admin)):
users = list_users_service()
return users
توی مثال بالا میتونید چندین لایه از وابستگی رو ببینید که به خوبی با Depends مدیریت شدن. حالا اگه این سیستم وجود نداشت چی؟
def list_users():
token = get_token()
user = get_current_user(token)
admin_user = require_admin(user)
...
اگه اون سیستم وجود نداشت باید قبل از هرکاری دونه دونه سرویس ها و لایه های پایین تر رو صدا میزدین و نتیجه اونهارو به همدیگه پاس میدادین. درواقع Depends میاد هر وابستگی ای که تعیین کرده باشین رو قبل از ورود به بدنه ی فانکشن اجرا میکنه و نتیجه ی وابستگی رو به آرگومان فانکشن پاس میده. در نتیجه شما در اولین خط بدنه ی فانکشن همه ی نتایجی که میخواین رو از طریق آرگومان ها در اختیار دارین.
پشت صحنه چه اتفاقی میوفته؟
FastAPI از بالا شروع کرد به نگاه کردن:
دید require_admin به get_current_user نیاز داره، بعد دید get_current_user هم به get_token نیاز داره، پس اول get_token اجرا شد، بعد get_current_user بعد هم require_admin. هربار خروجی یه فانکشن، ورودی فانکشن بعدی شد. درنهایت اگه مشکلی نباشه میرسیم به endpoint.
از کجا فهمید چی رو به کجا بفرسته؟
خب باید بگم که FastAPI به شدت به تایپ هینت ها وابسته است و خیلی ازشون استفاده میکنه. همین Depends هم با استفاده از تایپ هینت ها جای مقادیر رو درک میکنه. یه فانکشن توی پایین ترین لایه یه آرگومان با تایپ Header داره؟ خب Depends اون آرگومان رو توی درخواست دریافت میکنه به اون فانکشن میرسونه.
کجا ازش استفاده کنیم؟
هر وابستگی ای که نیاز داره یه پارامتری رو مستقیما از درخواست بگیره و روش پردازش انجام بده، و به نحوی قبل از فانکشن endpoint اجرا بشه و نتیجه ی آماده داشته باشه(درست همونطور که گفتم، قبل از بدنه ی اصلی فانکشن) باید با Depends استفاده بشه. مثلا گرفتن توکن از هدر یا چک کردن دسترسی ها، اتصال به دیتابیس
اما اگه فانکشنی که میخواید استفاده کنید ارتباط مستقیم با بدنه و اطلاعات ورودی از درخواست نداره و فقط برای انجام کاری یا پردازش داخلی باشه نیازی به Depends نداره. مثل ثبت نام کاربر که ممکنه دیتای خام و پردازش نشده ای از درخواست نیاز نداشته باشه و صرفا اطلاعات رو توی دیتابیس ذخیره میکنه
سعی کردم هر سوالی که برای خودم توی فرآیند این سیستم پیش اومد رو به بهترین شکل پوشش بدم. اگه مشکلی توی درک داشتین یا سوالی براتون مونده بود توی کامنت ها بپرسین.
#️⃣ #fastapi #python #backend
➖➖➖➖➖➖➖➖➖➖
🥷🏻 CHANNEL | GROUP
BY Ninja Learn | نینجا لرن
Share with your friend now:
tgoop.com/ninja_learn_ir/770