Skip to content

3주차 수요일 그룹 1

지찬우 edited this page Jul 10, 2024 · 1 revision

김현욱

  • 기본적으로 리팩토링을 진행하여 이번주 미션에 대해 진행한것은 별로 없습니다.

  • 세션에 대한 로직은 아래와 같은 구조를 가지고 있습니다.

  • SessionManager : 세션을 통합적으로 관리하는 객체입니다. 세션 id 생성, 세션 생성 및 저장, id 반환, 세션 생성시간, 마지막 접근 시간 업데이트 등의 책임을 집니다.

  • SessionStorage : 세션 객체를 관리합니다. 저장 및 삭제를 책임집니다.

  • Session : 세션에 대한 정보를 담당합니다. 세션 id, 생성 시간, 업데이트 시간 등을 조회할 수 있고, 세션 객체 안에 사용자의 attribute를 삽입, 삭제 할 수 있습니다. 또한 invalidation 을 책임집니다.

  • 쿠키 관련 부분은 response header에서 key값으로 multi value를 받을 수 있게 설정했기 때문에, response.addCookie 메서드를 이용하여 값을 관리할 것 입니다.

핸들러 인터페이스는 아래와 같이 default 로 선언하여 기본적으로는 MethodNotAllowed 를 throw 할 수 있도록 구현했습니다.

package codesquad.was.http.handler;

import codesquad.was.http.exception.HttpMethodNotAllowedException;
import codesquad.was.http.exception.HttpNotFoundException;
import codesquad.was.http.message.request.HttpRequest;
import codesquad.was.http.message.response.HttpResponse;

public interface RequestHandler {
    default void handle(HttpRequest req, HttpResponse res){
        switch(req.getMethod()){
            case GET->getHandle(req,res);
            case POST ->postHandle(req,res);
            case PUT ->putHandle(req,res);
            case PATCH -> patchHandle(req,res);
            case DELETE -> deleteHandle(req,res);
            case OPTIONS -> optionsHandle(req,res);
            case TRACE -> traceHandle(req,res);
            case HEAD -> headHandle(req,res);
            case CONNECT -> connectHandle(req,res);
        }
    }
    default void getHandle(HttpRequest req, HttpResponse res){
        throw new HttpMethodNotAllowedException("This method is not allowed");
    }
    default void postHandle(HttpRequest req, HttpResponse res){
        throw new HttpMethodNotAllowedException("This method is not allowed");
    }
    default void putHandle(HttpRequest req, HttpResponse res){
        throw new HttpMethodNotAllowedException("This method is not allowed");
    }
    default void patchHandle(HttpRequest req, HttpResponse res){
        throw new HttpMethodNotAllowedException("This method is not allowed");
    }
    default void deleteHandle(HttpRequest req, HttpResponse res){
        throw new HttpMethodNotAllowedException("This method is not allowed");
    }
    default void optionsHandle(HttpRequest req, HttpResponse res){
        throw new HttpMethodNotAllowedException("This method is not allowed");
    }
    default void traceHandle(HttpRequest req, HttpResponse res){
        throw new HttpMethodNotAllowedException("This method is not allowed");
    }
    default void headHandle(HttpRequest req, HttpResponse res){
        throw new HttpMethodNotAllowedException("This method is not allowed");
    }
    default void connectHandle(HttpRequest req, HttpResponse res){
        throw new HttpMethodNotAllowedException("This method is not allowed");
    }
}

마지막으로 테스트코드를 용이하도록 DI & IOC 구조를 채택해서 테스트 커버리지를 약 80% 까지 올렸습니다.

package codesquad.was.http.handler;

import codesquad.was.http.exception.HttpMethodNotAllowedException;
import codesquad.was.http.exception.HttpNotFoundException;
import codesquad.was.http.message.request.HttpRequest;
import codesquad.was.http.message.response.HttpResponse;

public interface RequestHandler {
    default void handle(HttpRequest req, HttpResponse res) {
        switch (req.getMethod()) {
            case *GET *->getHandle(req, res);
            case *POST * ->postHandle(req, res);
            case *PUT * ->putHandle(req, res);
            case *PATCH * ->patchHandle(req, res);
            case *DELETE * ->deleteHandle(req, res);
            case *OPTIONS * ->optionsHandle(req, res);
            case *TRACE * ->traceHandle(req, res);
            case *HEAD * ->headHandle(req, res);
            case *CONNECT * ->connectHandle(req, res);
        }
    }

    default void getHandle(HttpRequest req, HttpResponse res) {
        throw new HttpMethodNotAllowedException("This method is not allowed");
    }

    default void postHandle(HttpRequest req, HttpResponse res) {
        throw new HttpMethodNotAllowedException("This method is not allowed");
    }

    default void putHandle(HttpRequest req, HttpResponse res) {
        throw new HttpMethodNotAllowedException("This method is not allowed");
    }

    default void patchHandle(HttpRequest req, HttpResponse res) {
        throw new HttpMethodNotAllowedException("This method is not allowed");
    }

    default void deleteHandle(HttpRequest req, HttpResponse res) {
        throw new HttpMethodNotAllowedException("This method is not allowed");
    }

    default void optionsHandle(HttpRequest req, HttpResponse res) {
        throw new HttpMethodNotAllowedException("This method is not allowed");
    }

    default void traceHandle(HttpRequest req, HttpResponse res) {
        throw new HttpMethodNotAllowedException("This method is not allowed");
    }

    default void headHandle(HttpRequest req, HttpResponse res) {
        throw new HttpMethodNotAllowedException("This method is not allowed");
    }

    default void connectHandle(HttpRequest req, HttpResponse res) {
        throw new HttpMethodNotAllowedException("This method is not allowed");
    }
}

조희승

리팩토링할 대상을 찾을 목적으로 그룹 리뷰에 참여 했습니다.

  • 쿠키를 객체로 관리하기
  • 한곳에서 예외처리
  • 다양한 content-type을 지원하기 위해 reader 추상화 or byte[] 읽기
  • 멀티스레드에서 안전하게 동작하는 싱글톤 만들기

김수현

  • request processor를 디폴트 메서드를 포함한 인터페이스를 만들어두면 유연한 설계 가능
  • 정적 리소스 핸들러를 먼저 고려하는게 좋은지 마지막에 고려하는게 좋은지는 매핑된 url 수 vs static 핸들러 수에 따라 달라질 수 있다. 스프링은 정적 리소스 핸들러를 마지막에 고려하는데 아마 스프링은 정적 리소스를 서빙하기 위해서 사용되기 보다 앞단에 web server를 두고 사용하는 경우가 많기 때문일듯
  • 테스트 커버리지 살펴보기

박혜성

  • 목소리 조금 더 크게 해주세요~
  • 간단한 템플릿 엔진을 만들어서 동적인 html을 만들었습니다. 밖으로 빼서 라이브러리로 만들어보면 재밌을 것 같아요.
  • 템플릿 엔진을 사용하는 과정에서 문자열 reaplce()가 반복해서 호출되고 있어 비효율적인 부분이 있을 것 같아요.
  • 구조가 스프링과 유사해보이는 것 같아요.
  • http 요청 메시지를 읽어들이는 부분에서 실제 HTTP 메시지의 줄바꿈 형식과 달라지는 경향이 있습니다.
  • 목소리 조금 더 크게 해주세요~
  • 간단한 템플릿 엔진을 만들어서 동적인 html을 만들었습니다. 밖으로 빼서 라이브러리로 만들어보면 재맸을 것 같아요.
  • 템플릿 엔진을 사용하는 과정에서 문자열 reaplce()가 반복해서 호출되고 있어 비효율적인 부분이 있을 것 같아요.
  • 구조가 스프링과 유사해보이는 것 같아요.
  • http 요청 메시지를 읽어들이는 부분에서

오민석

  • static 남발로 인한 test 부족때문에 이를 고쳐야 할 것 같습니다
  • encoder, decoder를 앞에 만들어서 filter를 쓰면 좀 더 깔끔해 이를 고치면 좋겠습니다.
  • exception을 좀 더 세분화하여 진행하고 handler를 method 별로 바꾸면 더 좋은 코드가 될 거 같습니다.

지찬우

  • 핸들에서 한 번 캐치할 수 있게 예외 처리할 부분 지점들이 많아지다 보니까 매번 Response를 생성하기 힘들어 한 번 해두면 편할 것 같음
  • 핸들러 할 때 Exception 넘겨주면 그대로 StatusCode를 꺼내옴
  • 예외 던질 때 throw HttpStatusException 할 때 상황에 맞는 StatusCode를 주입
  • 어떻게 핸들링할지 고민

👼 개인 활동을 기록합시다.

개인 활동 페이지

🧑‍🧑‍🧒‍🧒 그룹 활동을 기록합시다.

그룹 활동 페이지

🎤 미니 세미나

미니 세미나

🤔 기술 블로그 활동

기술 블로그 활동

📚 도서를 추천해주세요

추천 도서 목록

🎸 기타

기타 유용한 학습 링크

Clone this wiki locally