내일배움캠프/TIL

[Spring_4기 본캠프] 일정관리 앱 API 명세서와 트러블 슈팅 | Day 39

austindynasty 2024. 12. 10. 11:57

1. API 명세서 

 

처음 API 명세서를 작성하려고 했을 때는 각 컬럼이 무엇을 의미하는지도 몰라서 작성하는데 어려움이 있었는데, 웹개발 프로젝트 이후로 두 번째로 작성하는 거라 큰 어려움은 없이 스스로 명세서를 작성할 수 있었다. 스프링에서 Swagger 의존성을 추가해서 자동으로 API 명세를 작성할 수도 있었는데 아직 Swagger는 익숙하지 않아서 애너테이션 사용법이나 결과물을 읽어내는건 좀 어려웠다.

하지만 현업에서는 Swagger를 자주 사용한다고 하니 꼭 시간을 내서 공부를 해봐야겠다.

 


 

2. 트러블 슈팅 

 

문제 1) 일정 전체 조회 BadGrammarException 

 

  최근 영어를 공부해놨던 것이 참 다행이라고 느끼는 순간들이 많았다. 우선 에러 메시지를 보면 당황스러우면서도 어떤 문제가 있는지 파악은 할 수 있다. BadGrammarException 이라는 단어를 보자마자 아 문법상 오류니까 내가 코드를 잘못 작성해놨다는 거구나, 라는 것을 단번에 알아낼 수 있었다. Column 'create_date' not found , create_date를 찾을 수 없다는거다. MySQL 테이블과 모든 코드를 천천히 살펴본 결과 테이블의 컬럼명은 createDate인데 코드에는 create_date라고 써놔서 인텔리제이가 테이블과 매칭을 못한 것이었다. 

  이번 과제에서는 클래스와 폴더가 더욱 세분화되어있어서 코드를 짤 때 헷갈린다는 이유로 일부러 클래스마다 이름을 다르게 붙였더니 일어난 문제였다. 변수명과 메서드명을 직관적으로 쓰라는 이유를 확실하게 느꼈다.

 

원인 ) 프로그램 내 변수명과 데이터베이스 테이블의 컬럼명이 상이해 매핑 불가 

해결 ) create_date 변수명을 테이블의 컬럼명에 맞게 createDate로 수정 후 프로그램과 API 정상 작동 확인


 

문제 2 ) 작성자의 입력이 할 일과 동일하게 출력

 

  API가 정상 작동하는지 테스트할 때 주의해야 할 것이 있다. '출력이 된다고 정상은 아니다' , 나의 부주의함으로 오류가 있다는 것을 뒤늦게 알아차였다. POSTMAN으로 API를 작동시켰을 때 내용을 제대로 확인하지 않고 포맷이 정상적으로 출력되니 정상이라고 생각하고 넘어갔었는데, 수정 API를 실행시켰을 때 task의 내용만 수정했는데 author이 수정된 task 내용과 동일하다는 것을 알아냈다.

오류 메시지가 뜨지도 않아서 어디서부터 잘못되었는지 하나하나 살펴봐야했다. println() 을 사용해서 디버깅을 해봐도 프로그램 내에선 출력이 모두 정상적으로 작동되었다.

 이후 MySQL 테이블의 데이터를 확인했을 때는 작성자 컬럼에 정상적으로 이름 데이터가 들어있는 것을 확인했다.

그렇다면 author 필드에 잘못된 값이 매핑되어있을 가능성이 높았다. TodoResponseDto 클래스를 확인했는데 작성자가 올바르게 매핑되어있는 것을 확인했다.

다음 가능성으로 Repository 계층에서 데이터를 잘못 가져올 가능성이었다. 하지만 아무리 살펴봐도 잘못 매핑된 코드는 없었다.

그러다가 데이터베이스 테이블의 컬럼 순서와 rowMapper의 순서가 다르다는 것을 알아냈다. 알 수 없는 버그가 발생했을 때 당황해서 보이지 않던 것이 체념을 하고나니 rowMapper, columnLabel 이 두 단어의 뜻이 각각 열을 읽는 도구, 컬럼의 이름 을 뜻하는 것을 깨달았다.

테이블 컬럼의 순서대로 코드를 수정해주고 실행시켜보니 API가 정상적으로 작동되는 것을 확인할 수 있었다.

변경 전 순서 : id, task, author, pw, createDate, modifiedDate
author와 task 순서 변경

 

원인 ) rowmapper 의 컬럼매핑이 데이터베이스의 컬럼라벨과 순서가 일치하지 않음

해결 ) 데이터베이스의 컬럼 순서에 맞게 코드를 수정후 정상 작동 


 

 

문제 3 ) 날짜 기준 일정 조회 시 필터가 작동하지 않음

 

  날짜를 기준으로 해당 날짜에 작성된 일정만을 조회하는 기능을 추가했는데, 다른 날짜의 일정까지 모두 조회가 되었다. 

이렇게 작동하는 것은 결국 전체 조회 기능과 다를 바가 없었다. 코드를 완전히 다르게 작성했는데 전체 조회와 동일하게 작동되다니.. 

당황스러우면서도 신기한 일이었다.

  오류를 해결하기 위해 코드를 이것저것 손보다가 500 internal server 에러가 발생해서, 영빈님한테 도움을 요청했다.

코드에서는 @RequestBody 애너테이션을 사용하고 있는데 URL에서는 파라미터 필터를 이용하고 있어서 발생한 문제였다.

애너테이션을 @RequestParam으로 변경해주고 실행해보니 정상적으로 작동되는 것을 확인할 수 있었다.

 

* 여기서 잠깐! @RequestParam에 required = false 옵션을 주면 파라미터의 필수 여부를 정할 수 있다. (값이 없을 수도 있다는 것을 설정)

 

원인 ) @RequestParam 과 @RequestBody 혼동

해결 ) 애너테이션을 @RequestParam으로 변경 후 정상 작동 확인 

 


사실 이외에도 수많은 에러가 발생했었는데... 주로 코드를 잘못 입력해서 나오는 500 internal server 에러가 많았다. (오타에 주의하자..)

기능을 하나 구현할 때마다 에러가 생겨나서 나중에는 트러블 슈팅을 생각하지도 못하고 에러를 수습하기에 바빴다. 

트러블 슈팅은 나의 양분이 될테니 까먹지 말고 기록하는 습관을 들여야겠다고 생각했다. 

 

 

3. @RequestParam, @RequestBody, @PathVariable 

: form 태그에서 데이터를 전달할 때 컨트롤러에서 데이터를 인자에 할당하는 방법들

 

1) @RequestParam

- 쿼리스트링으로 파라미터를 URL로 전송받을 때 URL 뒤에 붙는 파라미터 값을 가져온다.

- 전달받은 데이터를 URI상에서 찾는다.

- 데이터를 저장하는 이름으로 메서드의 파라미터명을 설정해줘야 한다.

- 해당하는 데이터만 받아올 수 있다. ( 가져오려는 데이터에 필터를 설정해 원하는 정보만 가져오기에 적절)

- 물음표 이후 key,value 형태 (ex. index?name=kim)

- 값을 설정해놓지 않으면 key값이 존재하지 않을 경우 에러가 발생한다.

- required = true / required = false 를 적어 설정을 변경할 수 있다. 

- 예시 : 게시판에서 특정 회원의 정보 페이지를 가져오려고 할 때

 

2) @RequestBody

- HTTP 요청의 Body가 담긴 값을 자바 객체로 변환한다. 

- JSON 데이터를 원하는 타입의 객체로 변환해야 하는 경우에 사용하기 적절하다.

- 주로 비동기 처리 구현 시 사용한다.

- 예시 : 작성했던 글의 제목을 수정하려고 할 때 수정하려는 제목의 ID와 수정 데이터가 포함된 요청 본문을 받을 수 있음

 

3) @PathVariable

- URI 경로의 일부를 메서드 매개변수에 바인딩할 때 사용한다.

- URL 경로에 포함된 변수 값(경로변수)을 추출할 때 사용한다. 

- 기본값을 설정할 수 없으며, 경로 변수는 필수이다.

- 예시 : 일정 리스트에서 특정 일정을 단건으로 조회할 때 {id} 경로 변수를 통해 일정 ID를 전달받음