존재하는 태그 추천 (맘같아선 옆에 몇건의 게시글이 등록되었는지도 표시하고싶지만, 아직 프론트 지식이 부족해서.. 포기했다 @_@)전보다 훨씬 깔끔하게 해시태그를 등록할 수 있게 되었다.캐릭터를 등록했을때 모습... 아직 css가 익숙치 않아서 최대한 노력해봤지만, 그래도 이미지를 크롭해서 캐릭터 얼굴만 표시하도록 구현했다. 추후에 더 업그레이드 해서 캐릭터를 3개까지 등록이 가능할때 해당 레이아웃이 그나마 제일 나을거같다고 생각해서 밑에 붙였다. (오른쪽에 붙이면 풀스크린일때 너무 떨어져있기때문에)
오늘 겪었던 문제 🤔
문제라기보단 성능관련 문제가 있었다.
Tagify의 옵션중 input이 자바스크립트의 keyup과 기능이 거의 똑같았는데, keyup 관련 기능을 구현할때, 매번 고민한던게 있었다.
글자마다 ajax 통신을 해버리면 안녕 이라는 결과를 검색할때 6번의 통신을 하게된다.
프론트에서 해결할 수 있을거같아서 스쳐지나가듯이 찾아봤던 기억중에 setTimeOut 이라는 메소드가 있었던거 같아서 엄청 검색을 했었다.
한글로 검색하기엔 적절한 태그를 찾지 못했고, 영어로 검색했을때 다행히 나같이 생각을 한 외국 개발자가 있었다.
전역변수로 timeout 변수를 만들어주고, 마지막 입력을 하기 직전까지 매 입력마다 변수에 메소드를 저장하고, 마지막 입력 직전까지는 실행되야하는 메소드를 모두 null처리 시켜서 없애주고, 마지막 메소드만 실행할 수 있도록 변경했다.
해당 로직은 나중에 검색어 로그 조회라던가, 비슷한 로직으로 캐릭터 검색등등 여러 부분에 쓰일 수 있을거같아서 기록을 해야겠다 다짐했었다.
오늘 해결한 오류 🤔
오늘의 배운점🤔
setTimeout 과 clearTimeout
좀더 효율적으로 이벤트를 다루기 위해서 알고있어야 할 것 같았다.
닉네임 중복조회 같은 로직에 keyup에 사용하면 좋을거같다.
노드 모듈을 스프링부트에서 사용하는법
기존에 꾸준히 제이쿼리 플러그인을 로드해서 사용중이었는데, npm을 스프링부트에 적용시키는 법도 있더라.
단순히 resources 폴더에 진입 후 npm init -> install 패키지 를 하고 핵심 js파일을 로드해오면 됐었다.
생성자가 클래스를 읽어오지 못해도 프론트에서 정상적으로 로드가 되더라... 앞으로는 npm으로 더 사용하기 쉽게 설치해야겠다.
캐릭터 정보 불러올시에 스프링 Async 기능을 이용해 비동기처리로 받아오도록 구현했다. (속도가 조금 빨라졌으려나..? 실감이 되지 않아서 불안정한 작업을 할 바엔 돌려놓는게 좋겠다라는 생각으로 두고보고있다. 하지만 캐릭터 정보는 내가 처리하는 데이터가 아닌 외부에서 안전한 데이터를 가져오는것이니.. 아직 확실하지 않다.)
반투명으로 알림이 등장한다. 새 알림이 등장할경우 위에 쌓이지 않고 기존의 알림이 사라지고 다시 알림이 등장한다.
오늘 겪었던 문제 🤔
해당 기능을 구현할때 보통 프론트쪽에서 세션스토리지에서 토큰정보를 가져와서 구현하는 글들을 많이 보았는데 나는 세션스토리지를 쓰지 않던 상황이라 로그인시에 세션에 로그인 정보를 저장하고 뷰의 헤더에 로그인 정보를 인풋밸류로 저장해 로그인을 안했을땐 anonymousUser 로 입력하도록 하고, 로그인시에는 계정이름을 입력하도록 한 후에 구독을 하도록 했더니 동작이 되었다.
오늘 해결한 오류 🤔
오늘의 배운점🤔
Sse (Server - sent - event) 를 알게되었다.
기존에 알림기능을 구현했지만, 실시간으로 알림을 전달하도록 하는 기능은 구현하지 못해서 약간 애물단지? 굳이 구현했어야했나? 하는 느낌으로 Notification 도메인이 남아있었다.
마찬가지로 생각해보니 구조상 알림이 생성되어야 하는 동작에서 컨트롤러단에서 서비스를 분리해 로직을 실행한게 아닌, 각 도메인 서비스별로 레포지토리를 주입시켜서 생성시키고 있었다. 이건 결합도가 높아질 수 있는 행동 (이런식으로 코드를 짜게되면 부품처럼 사용하지 못하게 된다. )
따로 알림 서비스와 컨트롤러를 생성하고 분리를 진행했다. 훨씬 깔끔하고 보기 좋았다.
마찬가지로 알림이 필요한 기능에 단순히 Sse 메소드만 집어넣으면 전송이 되었다.
거기에 +@ 로 부트스트랩의 toast 에 대해서 알게되었다.
이제 alert() 가 아닌 토스트에 메시지를 띄워도 되겠다는 생각이 들었다...... 굿
랜덤한 직업과 닉네임을 부여한 후 , 해당 캐릭터가 등록을 원하는 모험단 소속으로 생성되었는지 체크 후 등록하도록 구현
사이트에서 검색되어 디비에 저장된 캐릭터들을 기반으로 명성기준 랭킹도 조회가 가능하다.캐릭터 장비를 클릭하면 상세 정보 조회가 가능하다. (장비별로 성장옵션이 다른 커스텀 장비가 존재하고, 추후에 데미지 계산을 위해서 장비 옵션을 참고해야할 순간이 올 수 있다고 판단하여 추가하였다.)장착 아바타 혹은 능력치 등등 해당 게임사에서 제공해주는 데이터중 핵심 데이터는 대부분 가져와서 출력할 수 있도록 구현했다.게시글에서 캐릭터를 언급하였을때캐릭터 상세조회 페이지에서 게시글에서 몇번 언급되었는지 확인이 가능하다.버퍼의 경우 해당 옵션처럼 버퍼전용옵션으로 핵심 버프 스킬을 강화시켜주는 옵션이 존재한다.신화 아이템의 경우 현 시즌에서는 거의 착용되지 않으나, 정확한 데이터 검증을 위해 신화 아이템의 경우와 신화아이템이 아닌 현 시즌 에픽아이템일 경우 두 가지 수 모두 챙겨서 버프스킬 레벨과 수치를 변경해주었다.조회를 위한 json 데이터가 값이 일정하게 들어오는것이 거의 없었다. 따라서 최대한 핵심 키워드에 맞춰서 값을 가져오고, 해당 값이 있는 value를 가져와야했기때문에 하드코딩이 불가피했다.흑흑.모험단 인증을 위해서 캐릭터를 검색하고 등록하기 전 모습랜덤으로 문자열과 현재 디비상 존재하는 캐릭터들 사이 랜덤한 직업이름을 가져와서 인증하도록 구현했다.인증이 완료되면 디비 내에 존재하는 같은 모험단 이름을 가진 캐릭터들이 해당 계정으로 귀속되고 다른 계정에서는 해당 캐릭터들이 소속된 모험단을 등록할 수 없게된다.
오늘 겪었던 문제 🤔
문제라기보다는 고민거리가 있었다.
해당 캐릭터의 레이드 데미지를 예측하기 위해선 스킬 계수(퍼센트 데미지) 정보가 필요한데, 게임사에서 제공해주는 데이터에서는 일정한 정보를 가진 데이터가 존재하지 않았다.
예를 들면 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초 안에 가져올 수 있는 데이터 수가 초과했을때 스레드 슬립 등)
등록한 캐릭터가 존재하지 않을때 (캐릭터는 글 내용과 관련하여 스펙 참고용으로 활용 예정)존재할때 (이미지 크롭에 애를 많이 먹었다..)
오늘 겪었던 문제 🤔
jpa의 양방향 관계맺기 문제
자식테이블이 아니고 독립적으로 운영될 수 있는 테이블에 대한 외래키 참조 제약조건 문제가 발생했다.
자꾸 기존의 테이블에 있는 DB를 참조하는게 아닌 새로 등록하고 참조하려고 했다.
글들을 찾아보니 무조건 외래키 제약조건을 걸지 않고 참조를 할 수 있도록 하는 방법이 있었다.
엔티티간 무한참조 문제
Dto <-> 엔티티 나 Dto <-> Response 객체 간 무한참조 오류가 발생했다.
오늘 해결한 오류 🤔
Jpa 양방향 관계 맺기 문제
@JoinColumn 어노테이션의 foreignkey 옵션을 사용해 제약조건을 없앴더니 정상적으로 객체 생성에 관여하지 않고 외래키를 참조할 수 있게 되었다. ConstraintMode.CONSTRAINT 로 해결 완료 (해당 옵션을 사용하려면 확실하게 인덱스 설정을 해줘야한다.)