python / / 2024. 9. 6. 19:43

[fastapi] 입력 출력값을 자동으로 camelcase로 매핑

FastAPI에서 입력과 출력 값을 자동으로 camelCase로 변환하는 방법은 주로 pydantic을 활용하여 가능하다. Python에서는 일반적으로 snake_case를 사용하지만, JavaScript와 같은 언어에서는 camelCase가 더 자주 사용된다.


예시를 위해 기본 api를 만들고 snake_case로 매핑하고 camel_case로 변경하는 방법을 알아보자.

1. FastAPI와 Pydantic 기본 구조

FastAPI는 Pydantic을 사용하여 데이터 검증 및 serialization을 처리한다. FastAPI의 모델은 Pydantic 기반으로 정의되며, Pydantic 모델은 snake_case로 작성되는 것이 일반적이다.

from pydantic import ConfigDict, BaseModel
from pydantic.alias_generators import to_camel

from fastapi import FastAPI

app = FastAPI()

class User(BaseModel):
    user_id: int = Field(description="아이디")
    user_name: str = Field(description="이름")
    age: int = Field(description="나이")
    favorite_foods: list[str] = Field(description="음식 리스트")

@app.get("/users/{user_id}")
def find_user(user_id: int):
    return User(
        user_id=user_id, user_name="홍길동", age=20, favorite_foods=["apple", "banana"]
    )

@app.post("/users/")
def find_user(user: User):
    return user

User 클래스를 만들고 조회, 생성 2개의 api를 만들었다. 조회는 응답값을 확인하려는 용도이며, 생성은 입력값을 확인하려는 용도이다. 실제 내부로직 구현은 중요하지 않으므로 더미 데이터를 리턴한다.

위 코드에서 User 모델은 snake_case로 정의되어 있다. 기본적으로 FastAPI는 이 모델을 그대로 사용하므로, 입력과 출력 모두 snake_case를 따른다.

api 조회

User 조회

GET localhost:8000/users/1

응답값

{
  "user_id": 1,
  "user_name": "홍길동",
  "age": 20,
  "favorite_foods": [
    "apple",
    "banana"
  ]
}

User 생성

POST localhost:8000/users
content-Type: application/json

{
  "user_id": 1,
  "user_name": "홍길동",
  "age": 20,
  "favorite_foods": ["라면", "김밥"]
}

응답값

{
  "user_id": 1,
  "user_name": "홍길동",
  "age": 20,
  "favorite_foods": [
    "라면",
    "김밥"
  ]
}

2. Pydantic Config를 사용하여 camelCase로 변환

Pydantic은 내부적으로 Config 클래스를 통해 다양한 설정을 커스터마이징할 수 있다. 이 설정 중 alias_generator 옵션을 사용하면 필드 이름을 자동으로 변환할 수 있다. 이 옵션을 사용하여 필드를 camelCase로 변환해 보자.

2.1. Pydantic의 model_config 설정

이제 Pydanticmodel_config를 수정하여 필드의 alias를 camelCase로 변환하도록 설정하다. alias_generator 옵션을 통해 필드의 alias를 자동으로 생성할 수 있다. 또한, populate_by_name=True로 설정하여 입력할 때는 snake_casecamelCase 모두 사용할 수 있게 한다.

from pydantic import BaseModel, Field, ConfigDict
from pydantic.alias_generators import to_camel

from fastapi import FastAPI

app = FastAPI()


class User(BaseModel):
    user_id: int = Field(description="아이디")
    user_name: str = Field(description="이름")
    age: int = Field(description="나이")
    favorite_foods: list[str] = Field(description="음식 리스트")

    model_config = ConfigDict(
        alias_generator=to_camel,
        populate_by_name=True
    )


@app.get("/users/{user_id}")
def find_user(user_id: int):
    return User(
        user_id=user_id, user_name="홍길동", age=20, favorite_foods=["apple", "banana"]
    )


@app.post("/users/")
def find_user(user: User):
    return user

위 코드에서는 User 모델의 필드 이름이 클라이언트 쪽에서는 camelCase로 노출된다. 예를 들어, user_iduserId로, user_nameuserName으로 변환된다.

2.2. FastAPI에서 camelCase 적용 결과 확인

이제 FastAPI에서 실제로 어떻게 동작하는지 확인해 보자. 다음은 예시 요청이다.

User 조회

요청

GET localhost:8000/users/1

응답

{
  "userId": 1,
  "userName": "홍길동",
  "age": 20,
  "favoriteFoods": [
    "apple",
    "banana"
  ]
}

User 등록

요청

POST localhost:8000/users
content-Type: application/json

{
  "userId": 1,
  "userName": "홍길동",
  "age": 20,
  "favoriteFoods": ["라면", "김밥"]
}

응답

{
  "userId": 1,
  "userName": "홍길동",
  "age": 20,
  "favoriteFoods": [
    "라면",
    "김밥"
  ]
}

입력에서 camelCase로 데이터를 보냈지만, FastAPI는 이를 자동으로 snake_case로 변환하여 내부적으로 처리하고, 응답 시에는 다시 camelCase로 변환하여 반환한다.

추가설명

  • populate_by_name : 입력값으로 alias 외에 name으로도 매핑할 수 있는지 여부 (기본값: False)
    • populate_by_name=False 라면 입력필드가 userName을 사용해야 한다.
    • populate_by_name=True 라면 입력필드가 userName, user_id 둘다 사용 가능하다.
반응형
  • 네이버 블로그 공유
  • 네이버 밴드 공유
  • 페이스북 공유
  • 카카오스토리 공유