What is Dependency?
의존성 주입이라는 것을 많이들 들어봤을 것이다. 그 전에 Dependency, 즉 의존성에 대해서 이야기 해봐야 될 것 같다. 의존성은 두 Class사이에서 나타나는 관계이다. A라는 Class가 있고 B라는 Class가 있으면, A라는 Class가 B라는 Class에 의존하고 있고 B라는 Class는 A에 의존하거나 그렇지 않은 경우를 말한다. 즉, A <-> B이기 때문에, 한 Class의 기능이 바뀌면 다른 Class에도 영향을 주는 것이다.
예를 들어보겠다, 다음과 같은 코드가 있다고 하자.
import datetime
class Customer:
customer_id: str = ""
customer_name: str = ""
class Order:
order_id: str = 0
order_customer_id: str = ""
order_date_time: datetime.datetime
def order(self, customer: Customer):
self.order_customer_id = customer.customer_id
위의 코드에서 Customer Class가 있고, Order Class가 있다. 여기서 Order Class가 Customer Class의 instance를 사용한다. 만약 customer_id를 str에서 int로 바꾼다면 Order Class에도 영향을 미치게 된다. 이러한 관계가 바로 의존관계라고 할 수 있다.
이러한 의존 관계는 여러가지 타입이 있다.
- Class Dependencies
- Interface Dependencies
- Method / Field Dependencies
What is Dependency Injection?
먼저 Dependency Injection(이하, DI)에서는 다음과 같이 경고? 아니면 위험성에 대해 이야기하고 있다.
- DI에서 객체간의 Tight Coupling은 아주 좋지 않다.
- 의존 Class는 의존 관계를 만들기에 아주 좋지 않다.
여기서 Tight Coupling은 Class들 간의 관계가 아주 강하게 연결, 의존되어 있을 때를 의미한다. 즉, 서로가 서로에 대해 책임소재를 묻는 관계라고 말할 수 있다. 이와 반대되는 Loose Coupling은 각자에게 책임이 있다는 것을 의미한다. 즉 의존 관계가 느슨하다고 볼 수 있다.
FastAPI공식 문서에서는 다음과 같이 DI를 설명하고 있다.
"Dependency Injection" means, in programming, that there is a way for your code to declare things that it requires to work and use: "dependencies".
프로그래밍에서 "의존관계 주입"이란, 코드에서 선언한 것들이 "의존관계"를 사용하기 위해 요구되는 것이다.
즉, FastAPI시스템에서 의존성주입이란 하나의 객체가 다른 객체의 의존성을 제공하는 테크닉이다. 이것을 좀 더 풀어서 설명해 보겠다.
- 의존성 : 서비스로 사용할 수 있는 객체, Client가 있다면 어떤 서비스를 사용할 것인지 지정하는 대신, 어떤 서비스를 제공하는지 말해주는 것이다.
- 주입 : 서비스를, 이것을 사용하려는 객체(Client)에 전달하는 것이다.
그렇다면 여기서 Dependency Inversion Principle (DIP) 에 대해서 설명하고 넘어가야 겠다.
DIP를 한말로 설명하면, "추상화에 의존한되, 구체화에 의존하면 안된다."라는 것이다. 이것을 좀 더 풀어서 설명하면, "고수준 모듈은 저수준 모듈의 구현에 의존하면 안되며, 저수준 모듈이 고수준 모듈에서 만든 추상 계층에 의존해야 한다는 것이다.
- 고수준 모듈 : 어떤 의미있는 단일 기능을 제공하는 모듈
- 저수준 모듈 : 고수준 모듈의 기능 구현에 필요한 하위 기능의 실제 구
위의 그림처럼, 저수준 모듈의 경우 자주 바뀌기 때문에, 추상화 모듈에 의존해야 한다. 이때 고수준 모듈은 아주 핵심 부분이라고 볼 수 있으며, 자주 바뀌면 안되는 부분이다. 이러한 DIP의 한 종류가 바로 IoC이다. 그렇다면 이제 설명이 어느정도 끝났으니 본격적으로 실제 코드를 보면서 DI가 어떻게 이루어지는지, FastAPI에서 어떻게 이루어지는지를 알아보고 가겠다.
Simple Example
from fastapi import Depends, FastAPI
app = FastAPI()
async def common_parameters(q: str | None = None, skip: int = 0, limit: int = 100):
return {"q": q, "skip": skip, "limit": limit}
@app.get("/items/")
async def read_items(commons: dict = Depends(common_parameters)):
return commons
@app.get("/users/")
async def read_users(commons: dict = Depends(common_parameters)):
return commons
가장 중요한 Line이 바로 common_parameters를 의미한다. 이것이 위에서 설명한 서비스를 의미한다. 그렇다면 여기서 Client는 무엇이 될까? 바로 read_items와 read_users가 된다.
다음 글에서 좀 더 자세하게 FastAPI에서의 Dependencies Injection에 대해 알아보겠다.
'Python > FastAPI' 카테고리의 다른 글
FastAPI 알아보기 - 클래스로서 의존, Dependency Injection, Dependency Injector (0) | 2023.01.28 |
---|---|
Events that tiangolo(Sebastián Ramírez) who is creator of FastAPI went through, and My Opinion (0) | 2023.01.15 |
FastAPI 알아보기 - Schema 다루기 혹은 DTO, Entity, DAO 등 (2) | 2023.01.05 |
FastAPI 알아보기 - Pydantic과 직렬화 (0) | 2022.12.24 |
FastAPI 준비 - FastAPI실행, Query Parameter, Request Body (2) | 2022.12.23 |