분류 전체보기255 11/16 - TIL : 좋은 테스트 코드 상품 관련 API와 리뷰 관련 API의 테스트 코드를 작성하며, 테스트 코드를 작성하는 이유와 좋은 테스트 코드란 무엇인지에 대해 고민하게 되었다. 🧐 테스트 코드 왜 작성할까? 디버깅 비용 절감(문제가 되는 코드를 빠르게 파악하여 수정 가능하다.)회귀 버그(이전에 제대로 동작하던 기능에 문제가 생김)에 대한 관리와 대처 코드에 대한 이해 (담당 개발자뿐만 아니라, 동료들의 이해를 도울 수 있다.)좋은 코드인지에 대한 고민과 검증 (좋은 코드는 테스트하기도 좋다고 한다.) 내가 생각하는 테스트 코드를 작성하는 이유는 위의 이유라고 생각한다. 테스트 코드를 직접 작성하면서 특히 네 번째 이유에 깊이 공감하게 되었다. 테스트 코드를 작성하는 과정에서 내 코드의 결합도가 높은가? 유연하게 대응할 수 있는 .. 2024. 11. 16. 11/15 - TIL : userDetails에 null이 들어오는 문제 오늘도 부지런히 개발을 하던 도중... 🐜 🐜 사용자 인가 로직을 추가하기 위해 userDetails를 통해 사용자 정보를 주입받는 과정에 문제가 발생했다! 분명히 어제 설정한 Postman 토큰 주입 방법으로 토큰을 넘겨주었는데도 JwtAuthorizationFilter에서 인증이 자꾸 실패되었다. 확인해보기 위해 다음과 같이 예외 처리하는 코드와 로그를 작성하고 다시 실행시켜보았다. 1234567891011121314151617181920212223 @ResponseStatus(HttpStatus.CREATED) @PostMapping public Prod.. 2024. 11. 15. 11/14 - TIL : POSTMAN 로그인 설정하기 오늘 User 인가와 관련한 작업을 시작했다. Postman으로 작업을 하는데, 로그인이 필요한 기능들은 Authorization 토큰이 필요해 이를 간편하게 설정하는 방법을 정리해본다. 우선 Postman에 로그인을 위한 API로 이동한다. [Scripts] - [Post-response] 으로 이동한다. Scripts를 작성할 수 있는 칸으로 이동해서 다음의 코드를 넣어준다. (토큰 값을 global 변수로 지정해주는 것)pm.test("set JWT token", () => { let data = pm.response.headers.get("Authorization"); pm.globals.set("token", data);}) 다음 로그인 API 명세에 따라 로그인을 진행해준다. .. 2024. 11. 14. 11/13 - TIL - Sub Query와 Join Query DSL을 사용해 Cursor 기반으로 가게 메뉴 목록 조회 기능을 구현하던 중, Sub Query를 사용한 방법과 Join을 사용한 방법의 차이가 궁금해 2가지 방법을 모두 테스트 해보았다. Shop의 UUID를 통해 Shop의 ID를 조회하고 조회한 ID 값과 일치하는 Product 목록을 조회하는 방법Join을 사용해 Shop과 Product를 연결하여, Shop의 UUID에 해당하는 shop_id를 가진 Product 목록을 조회하는 방법 2개의 쿼리의 차이를 비교하기 위해 실행 계획으로 살펴보았다. 방법 1. Sub Query EXPLAIN ANALYZESELECT *FROM p_product AS p where p.shop_entity_shop_id = ( sel.. 2024. 11. 13. 11/12 - TIL : git merge와 rebase, 반정규화 오늘 git 그리고 PR이라는 특강을 들었다. 그 중에서 가장 기억에 남았던 git merge와 rebase에 대해 정리해보려고 한다. merge vs. rebasemerge : 새로운 커밋(merge commit)을 추가하여 브랜치를 합침 각 브랜치의 히스토리(commit)이 그대로 유지되며 합친 흔적(merge commit)이 남는다. rebase : 특정 브랜치 위로 다른 브랜치의 커밋을 다시 적용하여 합침 하나의 브랜치에서 모든 작업이 이뤄진 것처럼 깔끔하게 보인다. 프로젝트를 해봤을 때 merge도 사용해보고 rebase 사용했었다. 팀이 어떤 전략을 선택해서 그것을 잘 따르는 것도 중요하다고 생각한다. 하지만, 가장 중요한 것은 merge, rebase 상관 없이 conflict를 잘 해결.. 2024. 11. 12. 11/11 - TIL : 팀프로젝트 장점! 주말에 개발 관련 공부를 하고 있었는데, 팀 슬랙에 팀원 분의 개발 현황이 올라왔다. 내가 경험해 본 페이징 전략 중에 Cursor 기반의 페이징 전략을 프로젝트에 적용 시키면 좋겠다는 생각이 들어 의견을 제안해봤다. 왜 Cursor 기반? : 페이징 기능을 구현할 때 가장 흔하게 접하는 전략은 Offset 기반이다. Offset 기반의 페이징은 구현하기는 쉽지만, 데이터가 많아질수록 성능이 저하된다는 단점이 있다. (주말에 정리해 본 글 - offset 기반 vs cursor 기반) 또한, 주문 플랫폼의 서비스 특성을 생각해 보았을 때, 사용자의 입장에서는 모든 음식점을 알기보다는 자신이 선호하는 음식점을 보고 싶을 것이다. 따라서, Cursor 기반으로 구현하는 것을 시도해 봐도 좋을 것 같았다. .. 2024. 11. 11. 페이지네이션 방식 - offset 기반과 cursor 기반 주문 플랫폼 개발을 위해 페이지네이션 처리 방식을 결정하고자 offset 기반과 cursor 기반 페이지네이션 방식을 공부해보고자 한다. 페이지네이션은 필요한 개수를 지정하고 정렬 조건에 맞춰 데이터를 가져온다. 이러한 페이지네이션 방법에는 2가지가 있다. offset 기반 cursor 기반 Offset 기반 offset 기반은 페이지네이션을 처음 구현하게 될 때 많이 접하는 일반적인 페이징 방법이다. SELECT * FROM [TABLE NAME]ORDER BY created_at DESCLIMIT 10 OFFSET 20;DB의 limit, offset 쿼리를 사용하여 페이지 단위로 구분해서 요청하고 응답한다. limit : 한 번에 가져올 데이터의 수를 지정 offset : 조회를 시작할 때 데.. 2024. 11. 10. Framework와 Library의 차이 Framework와 Library는 개발을 하게 될 때 개발자가 코드를 더 효율적으로 작성하고 기능을 구현할 수 있게 돕는 도구이다. 최근 백엔드 개발을 하면서, Framework와 Library의 차이점이 궁금해져서 이에 대해 알아보고자 한다. FrameworkFramework는 애플리케이션의 구조 또는 틀을 제공하며, 개발을 위한 기본적인 형태와 필수 요소를 포함하고 있다. 따라서, 개발자는 Framework가 제공하는 구조와 규칙을 따라야 한다. 이는 제어의 역전(IoC : Inversion of Control)이라고 한다. LibraryLibrary는 특정 기능을 수행하는 코드의 모음으로, 개발자가 필요할 때 호출해서 사용할 수 있다. 따라서, 호출하는 주체가 개발자이기 때문에, 애플리케이션.. 2024. 11. 9. DB PK 전략 - UUID를 PK로..? 이제까지 프로젝트를 수행할 때 DB PK 전략을 AUTO_INCREMENT를 사용했었다. 하지만, 이번에 주문 앱 개발 프로젝트를 하면서 DB PK의 전략에 대한 이야기가 나왔다. 일반적으로 사용하는 AUTO_INCREMENT 전략에는 몇 가지 문제가 있다고 한다. 따라서, 이 주제에 대해 팀원분들과 튜터님과 같이 나누었던 이야기 내용에 대해서 정리해보려고 한다. AUTO_INCREMENT 전략 문제점 다른 데이터들을 쉽게 추적할 수 있다. 분산 시스템에서 ID가 고유하지 않을 수 있다. 위의 문제점이 발생한다고 한다. 조금 더 자세히 알아보자. 1. 다른 데이터들을 쉽게 추적할 수 있다. 지금 쓰고 있는 티스토리 블로그만 봐도 알 수 있다. URL의 가장 뒤에 ~~~/[숫자] 글을 쓰면 숫자들.. 2024. 11. 8. 자바 기본 - System.out.println() 자바로 알고리즘을 많이 풀다보면, 결과가 잘 출력되는지를 확인하고 싶을 때가 있다. 그때 많이 사용하게 되는 것이 System.out.println() 이다. 하지만, System.out.println() 은 사용하는 것을 지양해야 한다고 한다.. 왜 그럴까..? System.out.println() 문제점우선, System.out.println()은 Stream을 통해 콘솔에 출력해주는 역할을 한다. 따라서, I/O 작업이 동반된다. 여기서 파악할 수 있는 점은 I/O 작업이 동반되기 때문에 실행하고 있는 해당 스레드에서 blocking I/O 처리로 인해 프로그램이 느려지는 결과가 초래된다는 것이다. 또한, 추가적으로 System.out.println()은 단순한 출력 기능을 제공할 뿐, 로깅과 관련.. 2024. 11. 7. 자바 기본 - 어노테이션과 리플렉션 스프링을 이용해 개발을 하다보면 어노테이션을 자주 마주하게 된다. 따라서, 어노테이션이 무엇이고, 어노테이션이 어떻게 리플렉션으로 동작하는지, 그리고 리플렉션이 무엇인지 알아보고자 한다. 어노테이션 (Annotation)코드에 추가할 수 있는 메타데이터의 한 형태로, @(at) 문자를 통해 표현할 수 있다. 어노테이션은 코드에 부가적인 정보를 제공하는 데 사용되는 표현 방법이다. 어노테이션은 소스 코드에 주석 형태로 추가되어 컴파일러, 런타임 환경 또는 다른 프로세스에게 특별한 정보를 전달한다. 대표적인 어노테이션 @Override : 해당 어노테이션이 선언되어 있는 메서드는 오버라이드됨을 컴파일러에게 알려줌 @Deprecated : 해당 메서드는 더 이상 사용되지 않는다는 것을 컴파일러에게 알려.. 2024. 11. 7. 자바 기본 - 람다와 스트림 최근 참여하고 있는 챌린지에서, 강사님이 람다와 스트림을 사용해야 하는 이유에 대해 말씀해주셨다. 그래서 공부를 해보고자 한다. 람다 표현식람다(lambda)란 Java에서 간결하게 익명 함수(이름 없는 함수)를 표현하는 방식이다. 람다 표현식은 함수형 프로그래밍을 구성하기 위한 함수식이다. 람다식으로 표현하면 메서드 이름, 매개변수 타입과 반환 값을 생략할 수 있고, 이를 변수에 넣어 자바 코드를 간결하게 만들 수 있다.타입을 생략해도 컴파일러가 생략된 타입 위치를 추론하여 동작하게 해주기 때문에 에러가 나지 않는다. 람다식은 인터페이스를 익명 클래스로 구현한 익명 구현 객체를 짧게 표현한 것이다. 따라서, 오로지 인터페이스로 선언한 익명 구현 객체만 람다식으로 표현 가능하다. 람다 표현이 가능한 .. 2024. 11. 7.