캐릭터 정보 불러올시에 스프링 Async 기능을 이용해 비동기처리로 받아오도록 구현했다. (속도가 조금 빨라졌으려나..? 실감이 되지 않아서 불안정한 작업을 할 바엔 돌려놓는게 좋겠다라는 생각으로 두고보고있다. 하지만 캐릭터 정보는 내가 처리하는 데이터가 아닌 외부에서 안전한 데이터를 가져오는것이니.. 아직 확실하지 않다.)
오늘 겪었던 문제 🤔
해당 기능을 구현할때 보통 프론트쪽에서 세션스토리지에서 토큰정보를 가져와서 구현하는 글들을 많이 보았는데 나는 세션스토리지를 쓰지 않던 상황이라 로그인시에 세션에 로그인 정보를 저장하고 뷰의 헤더에 로그인 정보를 인풋밸류로 저장해 로그인을 안했을땐 anonymousUser 로 입력하도록 하고, 로그인시에는 계정이름을 입력하도록 한 후에 구독을 하도록 했더니 동작이 되었다.
오늘 해결한 오류 🤔
오늘의 배운점🤔
Sse (Server - sent - event) 를 알게되었다.
기존에 알림기능을 구현했지만, 실시간으로 알림을 전달하도록 하는 기능은 구현하지 못해서 약간 애물단지? 굳이 구현했어야했나? 하는 느낌으로 Notification 도메인이 남아있었다.
마찬가지로 생각해보니 구조상 알림이 생성되어야 하는 동작에서 컨트롤러단에서 서비스를 분리해 로직을 실행한게 아닌, 각 도메인 서비스별로 레포지토리를 주입시켜서 생성시키고 있었다. 이건 결합도가 높아질 수 있는 행동 (이런식으로 코드를 짜게되면 부품처럼 사용하지 못하게 된다. )
따로 알림 서비스와 컨트롤러를 생성하고 분리를 진행했다. 훨씬 깔끔하고 보기 좋았다.
마찬가지로 알림이 필요한 기능에 단순히 Sse 메소드만 집어넣으면 전송이 되었다.
거기에 +@ 로 부트스트랩의 toast 에 대해서 알게되었다.
이제 alert() 가 아닌 토스트에 메시지를 띄워도 되겠다는 생각이 들었다...... 굿
랜덤한 직업과 닉네임을 부여한 후 , 해당 캐릭터가 등록을 원하는 모험단 소속으로 생성되었는지 체크 후 등록하도록 구현
오늘 겪었던 문제 🤔
문제라기보다는 고민거리가 있었다.
해당 캐릭터의 레이드 데미지를 예측하기 위해선 스킬 계수(퍼센트 데미지) 정보가 필요한데, 게임사에서 제공해주는 데이터에서는 일정한 정보를 가진 데이터가 존재하지 않았다.
예를 들면 A스킬의 옵션 설명 : ~~~공격 12타 {value1} x 12 \n ~~범위 {value2} px 이런식으로 데이터가 불규칙하게 되어있었다.
해당 게임사가 그렇게 데이터를 관리한다면 곧 그 게임사에서도 어떠한 알고리즘? 로직? 을 구현해 최종 스킬 데미지를 계산이 가능할텐데 , 도저히 내 머릿속에서는 방법이 떠오르지 않았다.
첫번째 방법으로는 스킬 데미지 설명 옵션을 가져온 후 , 핵심 키워드 (데미지, 공격, 스킬 등) 가 담겨있는 문자열만 뽑아서 value를 더하거나 곱해 계산하려고 했었다.
해당 방법은 고정된 곱셈 수 , px(범위) 등등 여러 문제가 있어서 포기
해당된 키워드중 데미지와 관련없는 키워드를 모두 제거 후 value 더하기
해당 방법 또한 마찬가지로 최종 퍼센트가 타 사이트와 맞지 않았다.
방법은 뭐가 있을까 ..? 다른 계수를 정리해놓은 사이트에서 일일히 데이터를 가져와서 해결하기엔 비효율적이다.
마찬가지로 버프력 또한 내가 지금 해당 게임을 하지 않고있으니 계산방법을 전혀 몰라서.. 일단 1차적인 방법으로 나중에 도움이 될 수 있도록 캐릭터를 조회할때 착용 장비의 상세 정보도 가져오도록 변경했다.
장비에 보면 고정적으로 스킬 데미지 퍼센트를 증가해주는 옵션이 있거나, 버프스킬의 스텟이나 공격력 증가 옵션을 강화시켜주는 옵션이 존재했기때문에, 해당 옵션으로 총 증가 스텟/퍼센트를 가공해서 버프력을 계산하거나 데미지를 계산하도록 하면 될 것 같았다.
최적의 방안은 아니지만, 해당 문제를 해결하기 위해서 한단계 더 나아갔다! 라고 생각하고있다 :)
오늘 해결한 오류 🤔
오늘의 배운점🤔
JPA의 @SqlDelete 기능과 @Where 을 알게되었다.
첫 프로젝트를 진행할때, 삭제 기능을 단순히 db상에 데이터를 남기고 컬럼하나의 값만 바꾸는 soft delete 가 아닌 , hard delete로 진행을 했었고, 추후에 soft delete 로만 바꿨는데, 이때 jpa에서 제공해주는 메소드를 사용하지 않고, setter로 일일히 자식객체까지 컬럼값을 변경해주었었다.
@SqlDelete 어노테이션으로 간단히 Update 쿼리문을 실행해 자식객체까지 cascade 설정을 해주면 알아서 컬럼값을 변경해준다.
+@ 로 deletedAt 변수를 선언해 추후에 일정 기간이 지난 데이터는 완전히 삭제가 가능하도록 건수를 남겨두었다. (관리자 페이지에서 구현을 하거나 자동으로 처리가 가능한 기능을 활용하면 좋을거같은데, 아직 배운게 없어서 모르겠다. 고민을 많이 해봐야겠다 :)
@Where 같은 경우엔 데이터를 불러올때 설정한 값들로만 불러올수있도록 (예를들어 삭제가 false인 데이터만) 설정할 수 있으나, 현재 프로젝트 같은 경우엔 회원의 게시글이나 댓글 기록이 삭제된 게시글,댓글도 확인이 가능해야했기 때문에 Where 어노테이션을 사용하면 예외가 발생했었다. 따라서 큰 변경점 없이 SqlDelete 어노테이션만 사용하고 Where 은 따로 사용하지 않았다.
RestApi 에 대해서 한번 더 공부해보았다.
현재 진행하는 프로젝트에 컨트롤러와 맵핑되어있는 uri들이 모두 엉망이라는것을 알게되었다.
아직 자세하게 공부하진 못했지만, rest api 의 정해진 규약? 에 맞춰서 uri들을 모두 수정해주었다.
특히 어떠한 자원이 담겨져있는 (게시판,캐릭터,유저 등등) 곳에는 구분자를 써서 복수로 표현해주는 (characters, articles, users) 같은 규칙을 다 갖고있도록 변경해주었다.
대문자를 쓰지 않는것과 중간을 구분해줄때 '-' 를 사용해주는 것 등 여러가지를 신경써서 수정해주었다.
남은 소소한 목표
-> 캐릭터 랭킹 페이지 구현 (직업별로 명성, 게시판에서 언급된 횟수, 혹은 전체 캐릭터 중 몇순위인지 등등)
-> 모험단 등록 관련 특혜 (개인 프로필 아이콘 모험단 등록 캐릭터들중 골라서 변경하고, 특별한 모험단 등록 아이콘 부여)
-> 모험단 페이지 (캐릭터 타임라인 혹은 모험단 전체 타임라인)
-> 관리자 페이지 (공지사항 등록 및 시간이 지난 삭제 게시글,댓글 삭제처리 등등 )
-> 캐릭터 데미지/버프력 산출 공식 알아내기
-> 데이터 가져올때 예외처리 (1초 안에 가져올 수 있는 데이터 수가 초과했을때 스레드 슬립 등)
자식테이블이 아니고 독립적으로 운영될 수 있는 테이블에 대한 외래키 참조 제약조건 문제가 발생했다.
자꾸 기존의 테이블에 있는 DB를 참조하는게 아닌 새로 등록하고 참조하려고 했다.
글들을 찾아보니 무조건 외래키 제약조건을 걸지 않고 참조를 할 수 있도록 하는 방법이 있었다.
엔티티간 무한참조 문제
Dto <-> 엔티티 나 Dto <-> Response 객체 간 무한참조 오류가 발생했다.
오늘 해결한 오류 🤔
Jpa 양방향 관계 맺기 문제
@JoinColumn 어노테이션의 foreignkey 옵션을 사용해 제약조건을 없앴더니 정상적으로 객체 생성에 관여하지 않고 외래키를 참조할 수 있게 되었다. ConstraintMode.CONSTRAINT 로 해결 완료 (해당 옵션을 사용하려면 확실하게 인덱스 설정을 해줘야한다.)