You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

8.0 KiB

의존성으로서의 클래스

의존성 주입 시스템에 대해 자세히 살펴보기 전에 이전 예제를 업그레이드 해보겠습니다.

이전 예제의 딕셔너리

이전 예제에서, 우리는 의존성(의존 가능한) 함수에서 딕셔너리객체를 반환하고 있었습니다:

=== "파이썬 3.6 이상"

```Python hl_lines="9"
{!> ../../../docs_src/dependencies/tutorial001.py!}
```

=== "파이썬 3.10 이상"

```Python hl_lines="7"
{!> ../../../docs_src/dependencies/tutorial001_py310.py!}
```

우리는 경로 작동 함수의 매개변수 commons에서 딕셔너리 객체를 얻습니다.

그리고 우리는 에디터들이 딕셔너리 객체의 키나 밸류의 자료형을 알 수 없기 때문에 자동 완성과 같은 기능을 제공해 줄 수 없다는 것을 알고 있습니다.

더 나은 방법이 있을 것 같습니다...

의존성으로 사용 가능한 것

지금까지 함수로 선언된 의존성을 봐왔습니다.

아마도 더 일반적이기는 하겠지만 의존성을 선언하는 유일한 방법은 아닙니다.

핵심 요소는 의존성이 "호출 가능"해야 한다는 것입니다

파이썬에서의 "호출 가능"은 파이썬이 함수처럼 "호출"할 수 있는 모든 것입니다.

따라서, 만약 당신이 something(함수가 아닐 수도 있음) 객체를 가지고 있고,

something()

또는

something(some_argument, some_keyword_argument="foo")

상기와 같은 방식으로 "호출(실행)" 할 수 있다면 "호출 가능"이 됩니다.

의존성으로서의 클래스

파이썬 클래스의 인스턴스를 생성하기 위해 사용하는 것과 동일한 문법을 사용한다는 걸 알 수 있습니다.

예를 들어:

class Cat:
    def __init__(self, name: str):
        self.name = name


fluffy = Cat(name="Mr Fluffy")

이 경우에 fluffy는 클래스 Cat의 인스턴스입니다. 그리고 우리는 fluffy를 만들기 위해서 Cat을 "호출"했습니다.

따라서, 파이썬 클래스는 호출 가능합니다.

그래서 FastAPI에서는 파이썬 클래스를 의존성으로 사용할 수 있습니다.

FastAPI가 실질적으로 확인하는 것은 "호출 가능성"(함수, 클래스 또는 다른 모든 것)과 정의된 매개변수들입니다.

"호출 가능"한 것을 의존성으로서 FastAPI에 전달하면, 그 "호출 가능"한 것의 매개변수들을 분석한 후 이를 경로 동작 함수를 위한 매개변수와 동일한 방식으로 처리합니다. 하위-의존성 또한 같은 방식으로 처리합니다.

매개변수가 없는 "호출 가능"한 것 역시 매개변수가 없는 경로 동작 함수와 동일한 방식으로 적용됩니다.

그래서, 우리는 위 예제에서의 common_paramenters 의존성을 클래스 CommonQueryParams로 바꿀 수 있습니다.

=== "파이썬 3.6 이상"

```Python hl_lines="11-15"
{!> ../../../docs_src/dependencies/tutorial002.py!}
```

=== "파이썬 3.10 이상"

```Python hl_lines="9-13"
{!> ../../../docs_src/dependencies/tutorial002_py310.py!}
```

클래스의 인스턴스를 생성하는 데 사용되는 __init__ 메서드에 주목하기 바랍니다:

=== "파이썬 3.6 이상"

```Python hl_lines="12"
{!> ../../../docs_src/dependencies/tutorial002.py!}
```

=== "파이썬 3.10 이상"

```Python hl_lines="10"
{!> ../../../docs_src/dependencies/tutorial002_py310.py!}
```

...이전 common_parameters와 동일한 매개변수를 가집니다:

=== "파이썬 3.6 이상"

```Python hl_lines="9"
{!> ../../../docs_src/dependencies/tutorial001.py!}
```

=== "파이썬 3.10 이상"

```Python hl_lines="6"
{!> ../../../docs_src/dependencies/tutorial001_py310.py!}
```

이 매개변수들은 FastAPI가 의존성을 "해결"하기 위해 사용할 것입니다

함수와 클래스 두 가지 방식 모두, 아래 요소를 갖습니다:

  • 문자열이면서 선택사항인 쿼리 매개변수 q.
  • 기본값이 0이면서 정수형인 쿼리 매개변수 skip
  • 기본값이 100이면서 정수형인 쿼리 매개변수 limit

두 가지 방식 모두, 데이터는 변환, 검증되고 OpenAPI 스키마에 문서화됩니다.

사용해봅시다!

이제 아래의 클래스를 이용해서 의존성을 정의할 수 있습니다.

=== "파이썬 3.6 이상"

```Python hl_lines="19"
{!> ../../../docs_src/dependencies/tutorial002.py!}
```

=== "파이썬 3.10 이상"

```Python hl_lines="17"
{!> ../../../docs_src/dependencies/tutorial002_py310.py!}
```

FastAPICommonQueryParams 클래스를 호출합니다. 이것은 해당 클래스의 "인스턴스"를 생성하고 그 인스턴스는 함수의 매개변수 commons로 전달됩니다.

타입 힌팅 vs Depends

위 코드에서 CommonQueryParams를 두 번 작성한 방식에 주목하십시오:

commons: CommonQueryParams = Depends(CommonQueryParams)

마지막 CommonQueryParams 변수를 보면:

... = Depends(CommonQueryParams)

... FastAPI가 실제로 어떤 것이 의존성인지 알기 위해서 사용하는 방법입니다. FastAPI는 선언된 매개변수들을 추출할 것이고 실제로 이 변수들을 호출할 것입니다.


이 경우에, 첫번째 CommonQueryParams 변수를 보면:

commons: CommonQueryParams ...

... FastAPICommonQueryParams 변수에 어떠한 특별한 의미도 부여하지 않습니다. FastAPI는 이 변수를 데이터 변환, 검증 등에 활용하지 않습니다. (활용하려면 = Depends(CommonQueryParams)를 사용해야 합니다.)

사실 아래와 같이 작성해도 무관합니다:

commons = Depends(CommonQueryParams)

..전체적인 코드는 아래와 같습니다:

=== "파이썬 3.6 이상"

```Python hl_lines="19"
{!> ../../../docs_src/dependencies/tutorial003.py!}
```

=== "파이썬 3.10 이상"

```Python hl_lines="17"
{!> ../../../docs_src/dependencies/tutorial003_py310.py!}
```

그러나 자료형을 선언하면 에디터가 매개변수 commons로 전달될 것이 무엇인지 알게 되고, 이를 통해 코드 완성, 자료형 확인 등에 도움이 될 수 있으므로 권장됩니다.

코드 단축

그러나 여기 CommonQueryParams를 두 번이나 작성하는, 코드 반복이 있다는 것을 알 수 있습니다:

commons: CommonQueryParams = Depends(CommonQueryParams)

FastAPI특히 의존성이 FastAPI가 클래스 자체의 인스턴스를 생성하기 위해 "호출"하는 클래스인 경우, 조금 더 쉬운 방법을 제공합니다.

이러한 특정한 경우에는 아래처럼 사용할 수 있습니다:

이렇게 쓰는 것 대신:

commons: CommonQueryParams = Depends(CommonQueryParams)

...이렇게 쓸 수 있습니다.:

commons: CommonQueryParams = Depends()

의존성을 매개변수의 타입으로 선언하는 경우 Depends(CommonQueryParams)처럼 클래스 이름 전체를 다시 작성하는 대신, 매개변수를 넣지 않은 Depends()의 형태로 사용할 수 있습니다.

아래에 같은 예제가 있습니다:

=== "파이썬 3.6 이상"

```Python hl_lines="19"
{!> ../../../docs_src/dependencies/tutorial004.py!}
```

=== "파이썬 3.10 이상"

```Python hl_lines="17"
{!> ../../../docs_src/dependencies/tutorial004_py310.py!}
```

...이렇게 코드를 단축하여도 FastAPI는 무엇을 해야하는지 알고 있습니다.

!!! tip "팁" 만약 이것이 도움이 되기보다 더 헷갈리게 만든다면, 잊어버리십시오. 이것이 반드시 필요한 것은 아닙니다.

이것은 단지 손쉬운 방법일 뿐입니다. 왜냐하면 **FastAPI**는 코드 반복을 최소화할 수 있는 방법을 고민하기 때문입니다.