Wordle Maker Project Spring 8일차

PROLCY·2023년 2월 1일
0

오늘은 2월 1일 8일차이다.

목표

  • 코드 정리
  • 웹소켓 공부 및 추가

진행

웹소켓은 일단 추가까지 다 끝났는데, 아직 확인해볼 것이 몇 개 더 있어서 내일 작성할 예정이다. 오늘은 어제 velog에 작성하지 못했던 코드들을 넣을 것이다.

    @PostMapping("/{makerNickname}/typing")
    public ResponseEntity<Object> typing(HttpServletRequest request, @RequestBody Map<String, String> body, @PathVariable String makerNickname) {
        String solverNickname = (String) request.getSession().getAttribute("solver");
        SolverDTO solverDTO = SolverDTO.builder()
                .nickname(solverNickname)
                .makerNickname(makerNickname)
                .build();
        solverDTO = solverService.getSolverDTOByNickname(solverDTO);

        String newWord = body.get("newWord");
        int listIndex = Integer.parseInt(body.get("listIndex"));
        String keyState = body.get("keyState");

        List<List<Map<String, String>>> wordList = parser.parseWordList(solverDTO.getWordList());
        List<Map<String, String>> word = parser.parseWord(newWord);
        if(wordList == null) {
            wordList = new ArrayList<>();
        }

        if(wordList.size() == listIndex)
            wordList.add(word);
        else if(wordList.size() > listIndex)
            wordList.set(listIndex, word);
        Gson gson = new Gson();

        String newWordList = gson.toJson(wordList);
        solverDTO.setWordList(newWordList);
        solverDTO.setKeyState(keyState);

        solverService.updateWordListAndKeyState(solverDTO);

        //웹소켓 추가

        return ResponseEntity.ok(null);
    }

POST solve/{makerNickname}/typing을 처리하는 라우터이다. 원래는 wordList만 업데이트하도록 되어 있었으나, 7일차에 언급했던 오류 때문에 keyState도 업데이트하도록 변경하였다. 대부분 파싱에 관한 코드라 특별할 건 없다.

    @PostMapping("/init")
    public Map<String, String> initializePost(HttpSession session, @RequestBody Map<String, String> body) {
        Map<String, String> response = new HashMap<>();
        String makerNickname = body.get("makerNickname");
        session.setAttribute("maker", makerNickname);

        MakerDTO makerDTO = MakerDTO.builder()
                .nickname(makerNickname)
                .build();

        List<SolversResponseDTO> solvers = solverService.getSolversByMaker(makerDTO);

        Gson gson = new Gson();

        response.put("solvers", gson.toJson(solvers));
        log.info(response.get("solvers"));
        return response;
    }

POST load/init을 처리하는 메소드이다. 요청으로부터 makerNickname을 가져와서 solverService의 getSolversByMaker를 활용하여 응답으로 보낼 SolversResponseDTO의 List를 가져온다. 이후 JSON으로 변형 후 응답에 담아 보낸다.

    @Override
    public List<SolversResponseDTO> getSolversByMaker(MakerDTO makerDTO) {
        Maker maker = Maker.builder()
                .nickname(makerDTO.getNickname())
                .build();
        List<SolverDTO> solverDTOS = solverRepository.findSolversByMaker(maker).stream()
                .map(solver -> modelMapper.map(solver, SolverDTO.class))
                .collect(Collectors.toList());

        List<SolversResponseDTO> solversResponseDTOS = new ArrayList<>();
        solverDTOS.forEach(solverDTO -> {
            String[] nicknameLetters = solverDTO.getNickname().split("");
            String wordList = solverDTO.getWordList();

            List<String> nicknameLettersList = new ArrayList<>(Arrays.asList(nicknameLetters));

            List<Map<String, String>> nicknameLettersObjectList = nicknameLettersList.stream().map(letter -> {
                Map<String, String> map = new HashMap<>();
                map.put("text", letter);
                map.put("state", "filled");
                return map;
            }).collect(Collectors.toList());

            List<List<Map<String, String>>> parsedNickname = new ArrayList<>();
            parsedNickname.add(nicknameLettersObjectList);

            List<List<Map<String, String>>> parsedWordList = wordList == null ? parser.parseWordList("[]") :parser.parseWordList(wordList);

            SolversResponseDTO solversResponseDTO = SolversResponseDTO.builder()
                    .nickname(parsedNickname)
                    .wordList(parsedWordList)
                    .build();
            solversResponseDTOS.add(solversResponseDTO);
        });
        return solversResponseDTOS;
    }

이게 그 getSolversByMaker 메소드이다. 매우 복잡하게 되어 있는데, 클라이언트에서 사용하기 좋게 변형을 하다보니 많이 복잡해졌다. 지금 생각해보면 이러한 처리는 클라이언트에 위임하는 것이 낫지 않은가 라는 생각도 든다. 지금은 이미 프론트엔드가 리액트로 만들어진 상태이고, 나는 api 서버를 구성하는 중이기 때문에 백엔드에서 다 처리하도록 하였다.

    @DeleteMapping("/delete/{makerNickname}")
    public String deleteMaker(HttpSession session, @PathVariable String makerNickname) {
        if(isClicked.get(makerNickname) == null || !isClicked.get(makerNickname)) {
            isClicked.put(makerNickname, true);
            Timer timer = new Timer(3000, e -> isClicked.put(makerNickname, false));
            timer.setRepeats(false);
            timer.start();
            return "oneClick";
        } else {
            session.setAttribute("maker", null);
            makerService.deleteMaker(MakerDTO.builder().nickname(makerNickname).build());
            return "doubleClick";
        }
    }

DELETE load/delete/{makerNickname}을 처리하는 메소드이다. 한 번 클릭하면 3초의 시간을 재는데, 이 안에 한 번 더 누르면 데이터를 삭제하도록 하였다. 이런 타이머 같은 부분도 클라이언트에서 처리 했어야할 부분 중 하나라는 생각이 든다. 한 번 클릭과 두 번 클릭의 요청 URL을 분리하면 충분히 구현가능할 것 같다.

내일 할 것

  • 웹소켓
  • 코드 정리

마무리

오늘도 많은 시간을 들였다. 특히나 웹소켓을 추가하는데 클라이언트랑 서버 둘 다 처리해야 되니까 더 시간이 많이 걸린 것 같다. 구현은 다 끝냈고, 내일 코드 정리하고 10일차에 마무리할 수 있을 것 같다.

0개의 댓글