Python/DRF

[DRF] 이론 정리(Serializer, REST API)

emhaki 2023. 3. 28. 12:56
728x90
반응형
SMALL

DRF(Django Rest Framework)와 Django 차이점이 뭔데?

Django로 프로젝트를 진행하다가 DRF를 사용해보면서 이해가 안됐던 점들이 많다. 지금은 어느정도 사용법에 익숙해진 느낌이지만 이론적인 부분을 정확하게 짚고 넘어가고자 차이점을 비교해보고자 한다.

DRF(Django REST Framework)

Django는 프론트엔드와 백엔드를 모두 처리해주는 풀스택 프레임워크이다. 프로젝트에 적용한걸 예시로 들어보면

@login_required
def create(request):
    form = QuestionForm(request.POST or None, request.FILES or None)
    if form.is_valid():
        temp = form.save(commit=False)
        temp.user = request.user
        temp.save()
        return redirect("questions:index")
    context = {
        "form": form,
    }
    return render(request, "questions/create.html", context)

위와 같이 return render를 통해 request, html, context를 반환해줬다. 그렇기 때문에 Django의 응답만으로 하나의 웹 페이지가 완성될 수 있었다.

 

하지만 웹이 점점 발전하면서 더 복잡한 기능들이 필요해졌고, Django만으로 그런 기능들을 개발하는게 어려워졌다. 특히 프론트엔드의 복잡한 기능들을 개발하는게 힘들어졌기 때문에 프론트엔드와 백엔드 각각의 전용 프레임워크로 따로 개발하는게 더 좋은 방식이 되었다.

DRF 데이터 반환

DRF는 HTML과 CSS 코드를 반환하지 않고 요청에 따라 처리된 데이터만 프론트엔드에 전달한다. 그동안 Django의 render를 통해 HTML과 CSS코드를 함께 반환하는데 익숙했던 나는 데이터만 프론트엔드로 전달한다는 개념이 이해가 잘 가지 않았었다. 이 부분이 Django와 DRF의 가장 큰 차이점이다.

DRF의 역할(직렬화)

프론트엔드는 데이터를 백엔드에 요청하고, 백엔드는 요청에 맞게 처리하여 데이터를 반환해준다. 이 과정에서 사용하는 데이터의 형식이 달라 문제가 되는데 이를 DRF의 직렬화 과정을 통해 해결할 수 있다.

# 파이썬 객체
kakao_login_user = get_user_model().objects.create(
            test=kakao_id,
            nickname=kakao_nickname,
            profileimage=kakao_profile_image,
            email=kakao_email,
            refresh_token=refresh_token,
        )

# 직렬화
{
 "test": "kakao_id",
 "nickname": "kakao_nickname",
 "profileimage": "kakao_profile_image",
 "email": "kakao_email",
 "refresh_token": "refresh_token",
}

Django는 백엔드에서 데이터를 처리할 때 python 객체 형식을 사용한다. 하지만, 프론트엔드에서는 보통 JSON 형식을 많이 사용한다. 이런 차이 때문에, 백엔드와 프론트엔드의 통신을 위해서 데이터 형식이 통일되어야 한다. 그 과정을 직렬화(Serialization)와 역직렬화(Deserialization)라고 한다. 직렬화는 서버에 파이썬 객체로 저장된 데이터를 JSON 형태로 바꿔주는 것이고, 역직렬화는 JSON 형태의 데이터를 파이썬 객체로 바꿔 주는 것이다. DRF가 바로 이 작업을 해준다.

REST란?

DRF의 REST란 무엇을 의미할까?

REST란 Representational State Transfet의 약자로 자원을 이름으로 구분하여 해당 자원의 상태(정보)를 주고 받는 모든 것을 뜻한다. 안전하고 효율적인 통신을 위해 API를 만들 때 따라야 하는 규칙으로, 이를 따르는 API를 REST API, 또는 RESTful API라고 한다. API가 RESTful하지 않더라도 데이터 통신은 가능하지만 많은 사람들이 공유한 규칙이기 때문에 잘 지키지 않으면 개발에 여러 문제가 생긴다.

REST 규칙

🔎 HTTP 메소드

HTTP 메소드는 프론트엔드와 백엔드의 통신에 사용되는 데이터 요청 방식이다.

HTTP 메소드 설명
GET 데이터 조회를 위해 사용
POST 데이터 생성을 위해 사용
PATCH 특정 데이터 수정을 위해 사용
DELETE 특정 데이터 삭제를 위해 사용

예를 들어 게시판에 보여질 게시글을 조회하려면 GET, 생성하려면 POST, 수정하려면 PATCH, 삭제하려면 DELETE 메소드를 사용해야하지만 게시글을 생성할 때 POST가 아니라 GET을 사용하면 API가 RESTfull하지 않다고 할 수 있다.

🔎 상태 코드

백엔드로 전달받은 요청이 잘 처리되었는지 표시해 주는 걸 상태 코드라고 한다. RESTful API가 되려면 요청이 처리된 결과에 맞게 적절한 상태 코드가 반환되어야 한다.

# 데이터 URL에 파일이 없는 경우
if not urllib.request.urlopen(url):
   return Response({'error': '데이터 URL에 파일이 없습니다.'}, status=status.HTTP_404_NOT_FOUND)

만약에 데이터가 정상적으로 조회됐다면 200 OK, 잘 생성됐다면 201 Created를 반환해야 한다. 이를 통해 응답된 데이터를 확인하지 않고 상태 코드만으로 결과를 확인할 수 있다.

🔎 URL 설계

HTTP 메소드 설명 URL 예시
GET 데이터 조회를 위해 사용 /movies
POST 데이터 생성을 위해 사용 /movies
GET 특정 데이터 조회를 위해 사용 /movies/:id
PATCH 특정 데이터 수정을 위해 사용 /movies/:id
DELETE 특정 데이터 삭제를 위해 사용 /movies/:id

또한 URL의 마지막 부분에는 슬래시(/)를 사용하면 안된다. 슬래시는 URL에서 의미를 구분해 주는 역할을 하기 때문에, 마지막에 슬래시가 있는 것과 없는 것은 서로 다른 자원으로 구분된다.

# bad
http://localhost:8000/popular_movies

# Good
http://localhost:8000/popular-movies

URL에서 구분자를 사용하려면 언더바(_) 대신 하이픈(-)을 사용해야 한다. 언더바는 문자로 인식되기 때문에 구분자의 역할을 하지 못한다. 또한 대문자와 소문자는 아예 다른 글자로 인식되기 때문에 소문자로 작성해야 한다.

728x90
반응형