Dev_Henry

[Spring] 자바 네이밍 컨벤션의 중요성 본문

Web/Spring

[Spring] 자바 네이밍 컨벤션의 중요성

데브헨리 2023. 7. 20. 09:29
728x90

프로그래밍 언어들을 공부한지도 시간이 꽤 흘렀고 물론 이제까지 네이밍 컨벤션을 지켜서 코딩하는 것이 좋다는 것을 알고있었다.

자바에서는 가장 기본적인 규칙중 카멜케이스 사용변수명은 소문자, 클래스명은 대문자로 시작하는 것 또한 잘 알고있었고 이제까지 그렇게 코딩을 했었지만 나는 이게 개발에 어떤 문제를 일으킬만큼 중요한 것이라고는 생각하지 못했고 단순히 '개발 중 내가, 혹은 협업하는 동료가 헷갈리지 않도록 통일성을 지키는 것' 정로도 생각하고 있었다.

이제까지 학부생활 중 팀프로젝트로 협업한 규모들이 대부분 작았고, 같은 학생들 입장에서 고작 변수명으로 이래라 저래라 하는 것을 팀원들이 나쁘게 생각할수도 있겠다싶어 종종 지키지 않는 팀원들이 있어도 강요는 하지 않았었다.

모순적이게도 '협업을 위한 규칙' 정도로 생각하면서도 협업 상황에서 신경쓰지 않았던 것이다.

그리고 오늘 변수명 때문에 문제가 생겼다.

@PutMapping("/result")
    public ResponseEntity<ResultResponse> resultTournament(@RequestBody List<TournamentPostDTO> result){
        tournamentService.UpdatePosts(result);
        return ResponseEntity.ok(ResultResponse.of(UPDATE_TOURNAMENT_SCORE_SUCCESS));
    }

 

@RequestBody 를 이용하여 json 데이터를 dto객체로 받아오는데 이상하게 dto의 다른 값은 다 받아오는데 id필드값이 null로 들어오는 것이다.

그래서 찾아본결과 문제는 필드변수명이었다. 부끄럽지만 근본이 없어도 너무 없는 이름으로 변수명을 적어놨었는데 이것이 문제가 된 것이다.

 

 

근본없는 변수명 그만
 

----

변수명을 저렇게 적게된 과정은..

jpa를 사용해서 entity작성을 해야하는데 -> 디비의 칼럼명은 대소문자 구분이 없다보니 언더바를 사용한다 -> 말했듯 변수명 규칙을 크게 중요하게 생각하지 않은데다가, 이미 협업하는 팀원 중 네이밍 컨벤션을 어기고 작성한 코드들이 꽤 있었다. -> 그러니까 굳이 귀찮게 @column 사용해서 별도로 적지말고 엔티티 변수명을 언더바 케이스로 적자 -> 근데 저 개발 과정에서 내가 필요한게 토너먼트 포스트, 이벤트 포스트 두개였음 -> 다적긴 너무 기니까 젤 앞글자만 적어서 구분하자 -> 근데 보통 앞글자만 적을때는 대문자로 적는게 국룰아닌가? -> 그럼 T_post, E_post 로 해야겠네..

----

이런 의식의 흐름으로 지어진 변수명이다. 뒤에 post는 또 왜 P가 대문자인지는 나도 잘 모르겠다.

아무튼 이게 문제가 된 이유는 스프링이 json데이터를 가져오는 과정에 있다.

내가 생각했어야 하는 것은.. 프레임워크나 라이브러리를 사용하는 것 또한 다르게 생각하면 그 라이브러리 제작자와 협업을 하는 것이라고 볼 수도 있지 않을까? 라는 점이다.

 

스프링은 기본적으로 자바 네이밍 컨벤션을 따르기 때문에 앞의 두글자는 소문자로 받아온다고한다.. 그래서 json안에 데이터를 T_Post_id라고 적어 데이터를 보내더라도 스프링 jackson이 해석하고 가져올때는 t_Post_id가 되고 변수명이 달라지기 때문에 필드를 못찾고 null이 된다는 것.

(+ 24/03/17

@RequestBody로 Json데이터를 받으면 MappingJackson2HttpMessageConverter를 사용해 직렬화,역직렬화 동작을 진행한다.

그리고 Jackson컨버터는 내부적으로 ObjectMapper를 사용하여 변환을 하는데, key값을 매핑하는 규칙이 정해져있다.

객체에 존재하는 getter를 이용해 필드명을 알아낸 뒤에 json key값과 매핑하는 방법으로 바인딩해준다.

그렇다면 getter로 필드명을 어떻게 알아내는가?.

getter는 일반적인 메서드라고 생각하기보다는 정해진 문법이라고 생각해도 좋을만큼 어디서나 사용하는 메서드이고, 작성방법이 일반화되어있다. 그러니 Lombok같은 라이브러리도 흔히 사용하고, 자동완성으로 작성하는 경우도 많다.

그 일반화된 방법이란 : 'get + 필드명' 으로 메서드명을 지으며, 이때 물론 자바의 컨벤션인 카멜케이스를 따라 필드명의 첫글자를 대문자로 적는다.

이렇게 일반적인 방법이 있으니, ObjectMapper는 이것을 반대로 뒤집어서 필드명을 유추한다.

jackson의 네이밍 컨벤션은 기본적으로 java Bean 네이밍컨벤션을 따른다. 조금 차이가 있지만(시작 두글자 대문자 케이스) 기본적으로 첫 문자를 소문자로하는것은 같다.

그리고, 난 변수명을 대문자로 시작하는 짓을 저질러버렸고, 내부적인 로직들을 거치며 대소문자가 바뀌어버려 바인딩에 실패한 것.)

결론 : 규칙은 지키라고 있는 것이다.

 

 

참고 : https://yungenie.tistory.com/16

https://velog.io/@ssol_916/RequestBody%EB%A1%9C-%EB%B0%9B%EC%95%98%EB%8A%94%EB%8D%B0-null%EC%9D%B8-%EA%B2%BD%EC%9A%B0

 

728x90
반응형