본문 바로가기

FastAPI

의존성 주입 - 2

 

의존성 주입 - 1에서와 같이 작성된 func_params가 반환하는 것은 dict 형태의 데이터 타입니다. 따라서 q["q"]에 대해서는 접근이 되지만 q.q는 접근이 되지 않습니다. 

 

값에 조금 더 편하게 접근을 하기 위해서 class 형태로 값을 저장해서 접근하는 방법이 있습니다.

 

 

의존성 주입 - 1

의존성 주입은 코드의 재사용성을 높여주고, 반환하는 객체의 사용을 쉽게한다는 장점이 있습니다. 반환하는 객체의 사용을 쉽게하는 것은 객체가 생성이 되는 과정은 관심이 없고, 그냥 사용

kbgw2001.tistory.com

 

클레스로 접근하는 형태의 main.py는 코드는 다음과 같습니다.

 

import uvicorn
from typing import Optional
from fastapi import FastAPI, Depends

app = FastAPI()


items = ({"name": "Foo"}, {"name": "Bar"}, {"name": "Baz"})


class ClassParams:
    def __init__(
        self, q: Optional[str] = None, offset: int = 0, limit: int = 100
    ):
        self.q = q
        self.offset = offset
        self.limit = limit


@app.get("/items/class")
async def get_items_with_class(params: ClassParams = Depends(ClassParams)):
    response = {}
    if params.q:
        response.update({"q": params.q})

    result = items[params.offset: params.offset + params.limit]
    response.update({"items": result})

    return response

if __name__ == "__main__":
    uvicorn.run("main:app", reload = True)

 

위의 코드에서 params를 func_params라는 함수로 정의하는 것이 아닌 다음과 같이 class로 정의 했습니다.

class ClassParams:
    def __init__(
        self, q: Optional[str] = None, offset: int = 0, limit: int = 100
    ):
        self.q = q
        self.offset = offset
        self.limit = limit

 

이렇게 params를 정의 할 경우, class에 입력이 되어져있는 q와, offset, limit 값에 대해서 "." 옵션(params.q 와 같이) 와 같이 바로 값에 접근이 가능합니다.

 

이와 같이 params도 조금 아쉬운 부분이 있습니다. 그래서 가장 좋은 방법은 pydantic을 사용하는 것이 가장 좋은 방법입니다.

 

pydantic을 사용해서 params를 정의한 main.py의 코드는 다음과 같습니다.

import uvicorn
from typing import Optional
from fastapi import FastAPI, Depends
from pydantic import BaseModel, Field

app = FastAPI()


items = ({"name": "Foo"}, {"name": "Bar"}, {"name": "Baz"})


class PydanticParams(BaseModel):
    q: Optional[str] = Field(None, min_length=2)
    offset: int = Field(0, ge=0) # greater than or equal
    limit: int = Field(100, gt=0) # gt -> 0 보다 커야한다.


@app.get("/items/pydantic")
async def get_items_with_pydantic(params: PydanticParams = Depends()):
    response = {}
    if params.q:
        response.update({"q": params.q})

    result = items[params.offset: params.offset + params.limit]
    response.update({"items": result})

    return response

if __name__ == "__main__":
    uvicorn.run("main:app", reload = True)

 

대부분의 코드는 같습니다 !! 다음 pydantic의 BaseModel이라는 Class를 상속 받아서 params라는 새로운 Class를 만들었습니다. 

 

여기서 params른 pydantic에 객체이기 때문에 pydantic에서 제공하는 다른 method들도 사용할 수 있습니다.

또한, pydantic을 사용했기에 데이터 검증을 해볼 수가 있는데요 !! 

 

위에 pydantic으로 만든 params Class에 대한 code를 살펴보면, 

class PydanticParams(BaseModel):
    q: Optional[str] = Field(None, min_length=2)
    offset: int = Field(0, ge=0) # greater than or equal
    limit: int = Field(100, gt=0) # gt -> 0 보다 커야한다.

 

Field를 pydantic에서 import를 했습니다. 여기서 q의 기본 값은 None으로 했고, 최소 글자수를 2글자로 설정했습니다. 즉 2글자 이상은 입력을 받아야합니다.

 

offset도 마찬가지로 음수 값을 입력하지 못하게 ge(greater than or equal : 0보다 크거나 같음)을 0으로 설정 했습니다.

 

limit에서는 gt(0 보다 커야한다.) 0으로 설정했습니다. 만약 limit을 0으로 설정한다면, 아무것도 검색을 하지 않는다는 의이미기 때문입니다. 

'FastAPI' 카테고리의 다른 글

백그라운드 작업 - 1  (2) 2024.03.05
인증  (1) 2024.02.27
의존성 주입 - 1  (1) 2024.02.15
에러처리  (0) 2024.02.15
파일처리-2  (0) 2024.02.11