이전에 유저 알림 기능을 구현할때 JSON으로 응답하는 것에 익숙치 않아서 2번의 요청을 보내야 했다. 첫 요청에서 알림의 갯수를 카운트하고 알림이 있다면 알림을 다시 요청하고 HTML을 렌더링해서 사용자에게 보내주었다. 두 응답 모두 문자열로 이루어졌고 기능이 정상적으로 동작하기에 유지하고 있었으나 최근 HASH MAP을 공부하면서 파이썬의 DictJSON에 흥미가 생겨 알림도 JSON 응답으로 변경하고자 하였다. 아래에선 문자열 응답이 JSON 응답으로 변경될 때 어떻게 달라지는지 나열할 것이다.


문자열 응답

1
2
3
4
5
6
7
8
9
10
11
12
13
14
from django.http import HttpResponse

def notify_count(request):
    notify = Notify.objects.filter(to_user=request.user)
    notify_num = len(notify)
    return HttpResponse(str(notify_num))

def notify_content(request):
    notify = Notify.objects.filter(to_user=request.user).order_by('created_date').reverse()
    result_data = ''
    for notify_one in notify:
        data = { 'pk': notify_one.pk, 'infomation': notify_one.infomation, 'created_date': notify_one.created_date }
        result_data += render_to_string('board/part_render/notify_toast.html', data)
    return HttpResponse(result_data)

위와같이 notify_count에서 알림의 갯수를 알려주고 notify_content를 요청해서 알림을 미리 랜더링해서 다시 문자열로 응답하고 있다. 이 방식의 단점은 2번의 요청을 보낼때 발생하는 네트워크 지연과 DB를 불필요하게 2번이나 읽어와야 한다. 물론 중간에 특수문자 넣어서 한번에 보내고 split 시킬수도 있겠지만… 여하지간 위 부분을 JSON으로 응답하는 것으로 변경해보자.


JSON 응답

우선 필자가 어려움을 겪었던 부분은 딕셔너리를 리스트로 표현하는 것이었는데 계속 붙잡다가 어느순간 터득했다. 딕셔너리의 한 키를 리스트로 만들고 리스트에 딕셔너리를 append하면 된다. 여하지간 위에선 count, content를 두번의 요청에 의해서 받았지만 여기서는 countcontent를 한번에 응답해서 클라이언트가 count가 1 이상이면 컨텐츠를 랜더링 하도록 하였다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
from django.http import JsonResponse

def user_notify(request):
    if request.method == 'GET':
        notify = Notify.objects.filter(to_user=request.user).order_by('created_date').reverse()
        data = {
            'count': len(notify),
            'content': list()
        }
        if data['count'] > 0:
            for notify_one in notify:
                data['content'].append({
                    'pk': notify_one.pk,
                    'infomation': notify_one.infomation,
                    'created_date': timesince(notify_one.created_date)
                })
        return JsonResponse(data, json_dumps_params = {'ensure_ascii': True})

다만 데이터를 위와같이 반복문을 통해서 append를 진행하는 것이 맞는 것인지 의문이다. 더 효율적인 방법이 있을 것 같은데 그 부분은 나중에 찾아보도록 해야겠다.


느낀점

장고에서 RESTful을 라이브러리 없이 어떻게 구현할까 싶었는데 이 방법이 점차 익숙해지니 손쉽게 만들 수 있을 것 같다. 또한 이러한 방식이 확실히 백앤드와 프론트엔드를 분업이 온전해져 효율적인 방법이라고 생각된다. 다만 블로그 서비스는 RESTful로 변경시 서버사이드 랜더링 등 추가할 점이 많아서 이대로 유지하며 몇 부분만 변경할 예정이지만 개인 블로그 구독 서비스 정도는 RESTful로 구현하도록 해봐야 겠다.

WRITTEN BY

배진오

소비적인 일보단 생산적인 일을 추구하며, 좋아하는 일을 잘하고 싶어합니다 :D
im@baejino.com