How to use Django rest framework

[버즈빌의 누구나 궁금해하는 개발 이야기] How to use Django rest framework

766
SHARE

BUZZVIL 블로그에 소개된 글을 편집한 뒤 모비인사이드에서 한 번 더 소개합니다.

1. Django를 사용하게 된 배경과 적용 과정

버즈빌이 해당 프레임워크(Django)를 사용하게 된 지는 아마 한 1년 반 정도 전인 2015년 봄쯤이었던 것으로 기억합니다. 그 전에는 Django 함수를 기반으로 한 개발이 주로 되어 있었습니다. 그러다 새로운 프로젝트를 진행하게 되었고, 그 때 회사의 다른 개발자분들과 새로운 프로젝트를 진행할 스펙과 기술에 대해 정하던 중에, Front-end와 Back-end를 분리해야 할 필요가 있어서 알아보게 되었습니다. 그리고  Back-end에서는 Django rest framework를, Front-end에서는 Angularjs를 알게 되어 그때 Back-end 기술의 일환으로 Django Rest framework의 사용을 결정했습니다.

먼저, 기존의 코드와 Django rest framework를 사용해서 어떤 식으로 단점을 보완하였는지 말씀드리도록 하겠습니다. 첫 번째로, 아래 보이는 코드가 기존 프로젝트에서 view를 return 할 때 사용한 코드 입니다. 함수 기반의 view를 사용해서 작업했었습니다.

 

 

이 view 방식의 단점은 front-end 코드와 back-end 코드가 맞물려 있다는 단점과, html 코드가 아닌 다른 코드를 리턴해야 할 필요가 있을 경우, 모든 코드의 수정이 필요하다는 것입니다.

아래의 코드는 json을 리턴하고 싶을 때 사용했던 코드입니다. (더 좋은 방법이 있을 수도 있으나, 간단하게 parameter를 받아서 작업하였습니다.)

이 또한 마찬가지로 http method를 분기 처리할 때 똑같이 발생하는 문제였습니다.

이러한 문제가 발생함에 따라 처음에는 저기까지는 뭐 노가다로 하면 할 수 있다고 생각이 들 수도 있긴 합니다만, Front-end가 점점 복잡해짐에 따라서 “ID로 필터를 걸어주세요! 리턴되는 데이터가 너무 많으니 pagination처리해서 UI에 보여주고 싶어요!” 라는 요구 사항들이 들어오고, 많은 요구 사항에 대해 어떻게 유연하게 처리해 줄 수 있지? 라고 생각을 하게 되었습니다.

오랜 고민 끝에, “그래! 장고에서 pagination을 지원하니, 일단 그걸 쓰도록 해볼까?? filter는 어떻게하지?? 아 그냥 손수 parameter 받아서 구현하지 뭐 얼마나 많아 지겠어.” 라는 생각이 들어 구현 작업에 나섰습니다.

그리하여 나온 이 아래 코드가 filter와 장고에서 지원하는 pagination을 적용시킨 코드입니다. 보시면 try…except 같은 코드가 pagination처리할 때 보여서, 코드를 보기에도 좋아 보이지 않죠?

좋아.. 여기까지는 우리가 잘 버텼어!! 근데, 데이터 validation처리도 해야 하는데 어떻게 하지? 장고 Form을 이용하자!!! 음.. 그럼 사용할 때 마다 Form이 필요한 거겠네..라는 생각이 안 들 수가 없는데요. 그래서 고안한 방법이 아래의 코드입니다.

어찌어찌하여 여기까지는 잘 버텼다고 생각했지만 알고보니 아래와 같은 더 많은 요구사항들이 있었습니다.

권한 별로 데이터의 제한도 두고 싶고 한데 이런건 어떻게 처리하지?
URL별로 권한은 설정 할수 있는데, 데이터의 대한 권한은 처리할수 있을까??
날짜 데이터를 내려줄때 해당 유저의 로컬 시간으로 보내줄수는 있을까?

위의 문제점들을 해결하기 위하여 이 작업을 또 하긴 싫은데 어떻게 하지 생각하다가 이 단점들을 보안할 수 있고, 나중에도 사용할 수 있는 Django rest framework를 알게 되었고, 저희의 문제점을 해결해 줄 수 있을 거 같다는 생각이 들었습니다.

 

2. Django Rest Framework에 대하여

Django rest framework 의 장점을 말씀드리자면 다음과 같습니다.

– API 지원
– 다양한 authentication 지원
– class 기반의 구현 방식
– 유저 권한 별 데이터 제한 가능
– 다양한 return 타입 제공 e.g) json, csv, excel…
– custom을 통해 확장 가능

위의 장점들에서도 알 수 있듯이 Django Rest Framework는 API 레벨도 잘 지원하면서, Back-end와 Front-end를 분리할 수 있고, Django와도 잘 맞는 프레임워크였고, 더불어, 새로운 프로젝트를 진행하는 시점에서 새로운 기술을 사용하는 건 새로운 도전이라고 생각해서 사용하기로 했습니다.

그래서 저희가 처음으로 도입한 방법은 문서에 있는 class 베이스의 generics package에 있는 것을 상속받아서 구현하는 것이었습니다. 이게 처음에 짠 코드입니다. 위에 비교해서 엄청 깔끔해졌죠?

또한, url(N) === view(N) 이 생기는 관리상의 이슈와 확장성의 이슈를 해결할 수 있는 좋은 방법이 없을까 고민하던 와중에, Django rest framework에 Viewset과 Router를 통해 view들의 집합을 만들 수 있다는 것을 알게 되었고, 이것을 통해 위와 같은 관리상 이슈는 해결할 수 있다는 것을 알았습니다.

이 아래 코드가 viewset과 router를 사용했을 때의 코드입니다. 깔끔하게 정리되었죠??

3. 추가적으로 해결해야 할 문제들

이제 해결해야 할 문제는 페이징 처리와 filter에 관련된 내용인데요. 이 문제도 Django rest framework에서 제공하는 pagination_class와 filter_fields, search_fields ordering_fields를 쉽고, 보기 좋게 해결할 수 있었습니다.

pagination_class 는 페이징 처리시에 참조가 되는 class의 이름을 세팅하는 변수이고, 세팅이 되어 있을 경우에 리턴되는 데이터를 페이징 처리해서 보여줍니다. 페이징 처리를 하였을 때랑 페이징 처리를 하지 않았을 경우, return 되는 데이터의 구조가 달라지게 됩니다. (중요!!) 

  •  pagination_class가 세팅 되어 있을 때 return되는 데이터의 구조

  • pagination_class가 세팅 되지 않았을 때 return되는 데이터의 구조

  • filter_backends 변수는 해당 class로 요청이 들어왔을 때 사용할 filter들을 정의할때 사용됩니다. 밑에 예제에서 보면 저는 3개의 필터(SearchFilter, OrderingFilter, DjangoFilterBackend)를 사용 했습니다.

     – SearchFilter

– 사용법: url에 search parameter에 들어오는 값에 대한 filter설정을 할수 있습니다. e.g) www.superbong.com?search=daniel
– search_fields에는 search에서 들어온 값이 필터될 fields를 설정합니다.

    – OrderingFilter 

– 사용법: url에 ordering에 들어오는 이름으로 ordering을 설정할수 있습니다. (* 앞에 -가 있을 경우 내림차순으로 ordering이 정렬됩니다.) e.g) www.superbong.com?ordering=-id
– ordering_fields에는 ordering으로 사용할 fields를 설정하게 됩니다.

    – DjangoFilterBackend

– 이것은 url에서 fields이름으로 filter를 사용하고 싶을때, 사용하는 filter입니다.
– url 뒤에 parameter로 column=값 을 설정하여 사용하면 됩니다.
– filter_fields를 통해 column으로 들어올 fields를 설정할수 있습니다.
– 그 외에 들어오는 column에 대해서는 무시 됩니다.

짜잔!! 이 아래에 있는 코드가 filter와 ordering을 썼을때의 최종 코드 입니다.


Django rest framework의 또 다른 장점이라고 할 수 있는 건, 권한 및 유저 별 데이터의 포맷을 변경 하기 용이하다는 것입니다. 저희는 Serializer를 사용해서 포맷이나 데이터의 제한을 두고 있습니다. 아래와 같이 Serializer를 통해 client에 들어오는 데이터(to_internal_value)와 나가는 데이터(to_representation)의 변환을 쉽게 할 수 있습니다.

– to_internal_value :POST, PUT과 같이 데이터 변경이 있을 때 client에서 들어오는 데이터를 저장 전에 핸들링할 수 있는 함수입니다.

– to_representation: GET, POST, PUT과 같이 데이터 변경이 있고 난 후에 client에 값을 변환해서 보여줄 경우 사용하는 함수입니다.

4. 끝으로

Django rest framework를 쓰면서 느끼는 점은 완벽하지 않아도 규약이나 규칙을 통해 개발자의 개발 시간과 가독성을 올리는 데 한몫을 하였습니다.

그와 별개로 인제 Django rest framework를 사용한 후에 저희가 다음으로 신경 쓰는 부분은 테스트 인 것 같습니다. 개발자가 많아지므로 인해서 관리해야 하는 코드도 많아지고, 변경했을 때의 생각지도 않은 곳에서 발생하는 오류가 점점 커지면서 소모되는 리소스의 양도 점점 많아지고 있습니다. 그래서 지금까지는 Back-end API 레벨 단의 테스트만 진행하고 있는데, 앞으로의 고민은 Front-end에 대한 코드가 점점 커지면서, 테스트에 대한 Needs가 필요한데, 이것에 대한 처리를 어떻게 해야 좋을지, 화면 단의 테스트 코드까지 테스트코드로 진행해야 할지 고민해야 하는 큰 문제 인 것 같습니다. 이에 앞으로도 많은 고민이 수반되어야 할 것 같습니다.

원문 바로가기: How to use Django rest framework

 

 

 

Comments