wafflestudio/seminar-2020

405 POST method not allowed 에러에 대한 궁금증

Opened this issue · 5 comments

405 POST method not allowed에 대한 궁금증입니다.
(#207 의 문제와 비슷한 맥락이었습니다.)

action decorator를 통해 extra actions를 정의하던 도중 이해가 가지 않는 부분이 있었습니다. 아래 DRF 문서 예시처럼
# POST /api/v1/user/{user_id}/set_password/ API를 구현하려고 하는데요, 함수명(여기서는 def set_password(self, request, pk=None)의 set_password)에 따라 405 error가 발생하거나 하지 않는 이상한 현상이 나타났습니다.

image

특히 이번 과제 중 8번을 진행하면서 #POST /api/v1/seminar/{seminar_id}/user/ API의 함수명을 enroll, #DELETE /api/v1/seminar/{seminar_id}/user/ API의 함수명을 drop으로 하여 함수를 작성했었습니다.

하지만 전자에서만 405 error가 발생했고, 함수명을 바꿔보니 createssss, post, asdf 등은 되는데 특정 이름에서는 또 405 error가 발생했습니다. (결국 함수명을 post로 결정)

물론 어딘가에 존재하는 코드 때문에 이런 결과가 발생하겠지만 잘 찾지 못하여 질문드립니다.

참고:
https://www.django-rest-framework.org/api-guide/viewsets/#marking-extra-actions-for-routing
https://ssungkang.tistory.com/entry/Django-ViewSet-%EA%B3%BC-Router

이거 혹시 #207 과 같은 결의 상황 아닐까요? @YeonghyeonKO

어 저도 방금 207 확인하고 본문 수정했는데요,

@guzus @keeprainy 아하, 만약 그러한 문제라면 설명을 드릴 수 있습니다. @actionmethods엔 보시다시피 method string들의 list를 param으로 주는데요. 같은 uri에 여러 http method를 쓰려면 methods=[‘POST’, ‘DELETE’] 같은 식으로 하나의 view method에다가 action annotation을 주고, 내부에서 if self.request.method == 'POST’ 같은 식으로 분기를 타서 http method마다 다를 API의 동작을 처리하면 됩니다.

이 방식으로 해보겠습니다!

음 그런데 애초에 함수명에 enroll은 안되고 post는 되는 게 잘 이해가 가지는 않습니다 ㅎㅎ.. ( methods=[‘POST’, ‘DELETE’]에다가 action annotation을 하지 않은 상태에서)

그런데 DRF ViewSet 내에서 view method 이름을 HTTP method로 하는 것은, #158 에서 지적되었듯 위험한 측면이 있어 권장되지 않습니다. post() 라는 method가 의도하신대로(?) 동작한 것은 저 이슈를 잘 살펴보시면 알 수 있듯, 태생적으로 전혀 다른 이유입니다.(원래는 마찬가지로 안 동작했어야 했는데, 다른 이유로 동작해버리는 것) enroll()은 HTTP method 이름이 아니므로, 오히려 DRF ViewSet 내에서 올바르게 사용한 것인데, #207 에서의 이유로, 중복된 uri 경로로 여러 view method를 정의했으므로 뒤의 것(drop())에 의해 덮어써져서 정상동작하지 않은 것입니다.

감사합니다! 이해했습니다.