swsnu / swppfall2019

31 stars 22 forks source link

[HW3] HTTP response 반환 형태 관련 #150

Open jihoonrf opened 5 years ago

jihoonrf commented 5 years ago

HTTP response를 리턴하는 형태가 다양하게 있을 수 있는 것 같은데 HttpResponse( status = ... ) 만을 사용해도(HttpResponseNotAllowed, HttpResponseNotFound, HttpResponseBadRequest 등을 사용하지 않고) 과제 구현에는 문제가 없는 것이 맞나요? 만약에 그렇다면 위에서 언급한 여러 HTTP response를 위한 클래스들을 사용하는 것이 어떤 이점이 있는지, 혹은 실제로 어떻게 달라지는지 궁금합니다.

uyw4687 commented 5 years ago

어떤 이점이 있는지에 대해서는 무슨 에러인지 더 정확하게 알 수 있고, 코딩할 때도 status code를 외우지 않아도 할 수 있어서 편리하고 실수를 줄일 수 있습니다. 특히 HttpResponseNotAllowed와 같은 경우에는 아래의 구현을 보시면 response에 추가적인 구현이 되어 있어 번거로움을 덜 수 있습니다. https://docs.djangoproject.com/en/2.2/_modules/django/http/response/#HttpResponseNotAllowed

ktaebum commented 5 years ago

네 @uyw4687 께서 말씀해주신 이유인데요

아마 여러분께서 요즘(? 이미 배웠나요?) 배우고 계신 Writing a Good Code와 연관성이 큽니다.

우선 그냥 status code로 다 적더라도 결과적인 행동은 같습니다. 이건 저 위에 링크 타고 가보시면

class HttpResponseBadRequest(HttpResponse):
    status_code = 400

class HttpResponseNotFound(HttpResponse):
    status_code = 404

class HttpResponseForbidden(HttpResponse):
    status_code = 403

처럼 각 Response가 HttpResponse를 상속받고 status_code만 바꿔주는 것을 볼 수 있습니다. 이런식으로 프로그래밍을 하는 이유는 가장 첫 번째는 readability입니다.

여러분들이 작성해놓은 코드를 누군가가 읽어야할 때 HttpResponse(status=404) 보다는 HttpResponseNotFound() 라고 적혀있는 게 더 readability 측면에서 편하겠죠. 물론 이 경우에는 404 코드는 이쪽 업계에선 관용적 표현처럼 쓰일만큼 유명하지만 만약 읽는 사람이 status 코드가 뭔지 모르면 읽으면서 그걸 또 인터넷 검색하면서 찾아봐야 하고 그런 번거로움이 있습니다.

또 하나는 debuggability입니다. HttpResponseNotAllowed가 좋은 예시인데요 바로 윗 댓글에서 링크 타고 가보시면 이 친구 같은 경우에는

class HttpResponseNotAllowed(HttpResponse):
    status_code = 405

    def __init__(self, permitted_methods, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self['Allow'] = ', '.join(permitted_methods)

    def __repr__(self):
        return '<%(cls)s [%(methods)s] status_code=%(status_code)d%(content_type)s>' % {
            'cls': self.__class__.__name__,
            'status_code': self.status_code,
            'content_type': self._content_type_for_repr,
            'methods': self['Allow'],
        }

뭔가 추가적인 행동을 하는 것을 보여주는데요, 어떤 request가 안 되고 어떤 게 allow되어 있는지를 보여줍니다.

따라서 프론트엔드 개발자 입장에서, 어떤 request를 보냈는데, 그냥 NotAllowed status 코드만 오는 것 보다는 지금 어떤 request 때문에 NotAllowed가 되고 (request를 여러개 한 번에 보내는 경우에 유용하겠죠?) 어떤 게 가능한 건지를 response에 보내주면 디버깅 하기 훨씬 쉽겠죠?

비슷한 예로는 여러분이 과제 1때 하셨던 BabyNameParseError도 비슷한 역할을 해준다고 볼 수 있습니다. 그냥 FileNotFoundError 를 내보내는 것보다는 그 Exception에 추가적인 정보를 Wrapping해서 내보내 주면 편하구요, 단지 프론트엔드 개발자 뿐만 아니라 서버 관리를 하는 사람 입장에서도 언젠가 한 번 모아둔 에러 로그 분석할 때 편하게 분석할 수 있습니다.