본문 바로가기

👨‍💻 프로그래밍/📦 Backend 58

Gradle 기반 프로젝트에 Ktlint 적용하기 Gradle 기반 프로젝트에 Ktlint 적용하기 Ktlint란?Kotlint에서 코딩 스타일을 자동으로 통일시켜 주는 도구 컴퓨터는 똑같이 인식해도, 사람마다 여러 코딩 스타일이 다를 수 있습니다. 대표적으로는 대괄호가 있습니다.# 1번째 스타일fun main(){ println("Hello World!")}# 2번째 스타일fun main() { println("Hello World!")} 1~2명이서 작업한다면 이런 스타일의 차이가 크게 상관없지만 여러 명이서 작업하면 큰 문제가 됩니다. 이건 여러 이유가 있는데요. 제가 느낀 이유 3가지는...누가 작성했느냐에 따라 스타일이 너무 다르면 일관성이 떨어져 코드 읽기가 힘들어짐같은 부분을 수정하면 Git에서 Conflict이 나서 이걸 해소하느라 불필요한 시간을 소모하게 됨내가 작성한 코드라.. 2025. 2. 15.
@FunctionalInterface란? @FunctionalInterface란? 어떤 때 쓰는 걸까?interface인데 Abstract Method가 딱 1개 있는 경우 Abstract Method가 1개인게 왜 중요할까요? Abstract Method가 1개이면 interface를 구현하는 class를 직접 만들지 않고 여러 간결한 문법들을 써서 변수에 interface를 구현하는 값을 바로 할당할 수 있기 때문입니다. 예를 들면...Lambda 식Method Reference 실제로 유용한 예시는 아니지만 String을 조작하기 위해 interface를 만든다고 해 보겠습니다.@FunctionalInterfaceinterface StringTransformer { String transform(String input);}🐜 Lambda 식@FunctionalInterfa.. 2025. 1. 30.
(Spring 위주로) AOP 용어 정리 (Spring 위주로) AOP 용어 정리 AOP란?코딩을 하다 보면 공통적으로 해야 하는 작업들이 있습니다. 대표적으로 로깅 (Logging)입니다. 프로그램에 문제가 생겼을 때 문제를 찾게 해 주는 단서가 로깅입니다. 그래서 당연히 중요한 것들을 최대한 자세히, 많이 남기는 게 좋습니다.처음 요청이 시작할 때가 몇 시 몇 분이고 어떤 Payload가 담겨져서 왔는지,중간중간 어떤 함수들을 호출했는지,끝날 때는 몇 시 몇 분이고, 어떤 Response가 나갔는지등등 다양합니다. 문제는 로깅 프레임워크나 라이브러리를 만들지 않는 이상 로깅은 애플리케이션의 핵심 기능이 전혀 아니라는 겁니다. 하지만 꼭 중요하고 필요한 것이기 때문에 빼먹을 수는 없습니다. 이걸 수기로 하게 되면 문제가 2가지 있습니다.코드에 핵심 기능이 아닌 여러 부수 기능들을 위.. 2025. 1. 26.
MDC로 풍부한 로그 쉽게 남기기 MDC로 풍부한 로그 쉽게 남기기 기존 로깅의 문제점로깅 (Logging)은 문제가 발생했을 때 원인을 찾아내고 해결하기 위해 애플리케이션 곳곳에 남기는 정보들입니다. 당연히 이 정보들은 많으면 많을수록 좋습니다. 일반적으로 로그에 남기면 좋은 정보들은 다음과 같은데요.HTTP 요청 1개 1개를 구별할 수 있는 고유한 값(MSA 환경인 경우) 여러 MS 같의 요청을 묶을 수 있는 값(유저가 시작한 요청인 경우) 그 유저의 고유 값 (PK 등)요청 시작 시간애플리케이션의 버전개발 환경 (Live, Dev, Staging 등)이건 극히 일부의 정보들을 나열한 것 뿐입니다. 문제는 이걸 수기로 남기게 되면 많은 문제들이 있습니다. 일단 로그를 남길 때마다 저 정보를 다 포함해야 한다면... 얼마나 짜증 날지 상상이 되시나요?private va.. 2025. 1. 12.
🥒 피클 (PKL): 새로운 설정 관리 언어 알아보기 🥒 피클 (PKL): 새로운 설정 관리 언어 알아보기 설정 파일?프로그래밍을 하다 보면 여러 설정 값들을 다뤄야 합니다. 서버라면 어떤 포트에 띄울지, API 통신을 한다면 API Key 값, DB의 아이디/비밀번호까지... 이런 값들은 코드에 하드코딩을 해 놔도 되지만 여러 이유로 따로 설정 파일을 둬서 관리합니다.프로그램이 실행되는 환경에 따라 값을 다르게 하기 위해 (개발 환경, 운영 환경 등)코드가 공개된 경우 보안을 위해 민감한 값을 실행 시점에 주입받기 위해코드 수정 없이 설정 값만 빠르게 바꾸기 위해 이런 설정 파일을 위해 보통은 .yml, .properties, .json 이나 아니면 언어별로 특화된 DSL을 각자 만들어 씁니다. 자바 진영에서는 gradle 설정을 위해 Groovy나 Kotlin의 DSL을 사용합니다.하지만... 이런 설정 .. 2024. 11. 2.
Kotlin의 @JvmStatic 알아보기 Kotlin의 @JvmStatic 알아보기 사용법과 효과평상시에는 @JvmStatic을 신경 쓸 필요가 전혀 없습니다. 하지만 Java와 Kotlin을 같이 써야 한다면 Kotlin이 어떤 식으로 컴파일되는지 알아야 하고, Java와 다른 점이 있다면 보정해 줘야 합니다. @JvmStatic은 Kotlin의 companion object와 object를 보정해 주기 위한 annotation입니다.공식 문서를 보면 자세히 나와 있는데요. Calling Kotlin from Java | Kotlin kotlinlang.org 아래의 Kotlin 코드를 자바에서 호출한다고 하면...class ExampleClass { companion object { fun exampleFunction() {} }} 아래와 같이 해야만 동작합니.. 2024. 8. 12.
성능 개선 고민: 데이터를 Map으로 바꾸는 것은 언제 가성비를 갖게 될까? 성능 개선 고민: 데이터를 Map으로 바꾸는 것은 언제 가성비를 갖게 될까? 성능상의 문제리스트에서 특정 조건을 기준으로 데이터를 찾아야 함 일반적으로 데이터가 적을 경우 하나씩 돌면서 검색을 합니다. 데이터가 정렬 돼 있다면 속도가 빠를 수 있겠지만 그래봤자 O(n log n)입니다. 코틀린으로 표현하면 아래와 같은 코드가 됩니다.fun List.findById(id: String): Data? { return this.firstOrNull { it == id }} 하지만 데이터가 늘어나면서 성능 문제가 생기게 되면, 아래와 같이 Map으로 먼저 바꾼 뒤 찾게 됩니다. 그럼 Map을 만드는 데는 O(n)이 걸리겠지만, 접근은 O(1)이 걸리게 되면서 성능상 이점이 있습니다.val dataMap = data .groupBy { it.id } .toMap() fun Map.f.. 2024. 8. 1.
서버에 API Key를 하드코딩 하면 안 될까? 서버에 API Key를 하드코딩 하면 안 될까? 문제가 되는 부분과 일반적인 해결책일반적으로 API를 호출할 때는 API Key라는 거를 같이 넘겨야 합니다. 아무나 제한없이 API를 호출할 수 있으면 기업 입장에서는 여러 단점이 있기 때문입니다.호출제한을 할 수 없음디도스 (DDos) 공격의 대상이 될 수 있음수익화를 하기 어려움 당장 네이버의 API 문서만 봐도 호출제한이 있고, API를 호출하기 위해서는 회원가입을 한 후 API Key를 발급 받아야 합니다. 문제는 API Key를 어떻게 관리해야 할까입니다. 호출제한 정도만 있으면 API Key가 유출돼도 귀여운 정도에서 끝나지만, 만약에 쓴 만큼 과금되는 API거나 개인정보를 많이 담고 있는 API라면 API Key가 유출되는 거 자체가 너무 큰 위험입니다! 😨이를 위해 애플리케이션이 실행 .. 2024. 7. 27.
Scale-out이 Scale-up보다 효과적인 이유 Scale-out이 Scale-up보다 효과적인 이유 주의점해당 내용은 100% 검증된 정설이라기 보다는 제가 궁금해서 혼자 고민해 보고 이것 저것 찾아보며 얻은 결론입니다. 평소에 스캐일 아웃 (Scale-out)이  왜 더 효과적인지 의문을 품으셨던 분들이 조금이라도 궁금증이 해소됐으면 좋겠습니다.틀린 내용이나 다른 인사이트가 있으시면 언제든 댓글로 달아 주시면 적극 반영하겠습니다!Scale-Out? Scale-Up? 그게 뭔데 트래픽이 늘어나면 서버를 늘려야 합니다. 여기서 서버를 늘리는 2가지 방법이 있습니다.Scale-up (Vertical Scaling)은 서버 1대의 성능을 늘리는 겁니다. 메모리를 늘리고, CPU를 더 좋은 걸로 바꾸고, 네트워크 대역폭을 늘리고... 등등이 모두 Scale-up이라 할 수 있습니다.Scale-out (Hori.. 2024. 7. 10.
자주 쓰는 Kotlin Live Template 공유 자주 쓰는 Kotlin Live Template 공유 Live Template이 뭐임Jetbrains 계통의 IDEA에서 쓸 수 있는 Code Snippets 코딩을 하다보면 반복되는 패턴을 많이 마주하게 됩니다. 여기서는 거창하게 디자인 패턴 같은 거를 말하는건 아니고, 아래와 같이 사소한 것들을 말한 겁니다.for 문으로 같은 동작 n번 반복하기if 문으로 null 확인하기이런 자주 쓰이는 언어의 패턴을 짧은 단축키로 바로 칠 수 있게 해 주는 걸 Code Snippets이라고 합니다. 가장 유명한 Code Snippets이라면 Emmet이 있겠네요.Emmet은 HTML에서 쓰는 Code Snippets인데, 특히 반복해서 타이핑해야 하는 일이 많은 HTML에서 유용합니다. 예를들어 아래와 같은 HTML 코드를 .. 2024. 6. 2.
Spring에서 DB 예외 처리하는 법 알아보기 Spring에서 DB 예외 처리하는 법 알아보기 기존 DB Exception의 문제점Spring이 있기 전에 DB에서 오류가 나면 크게 3가지 문제가 있었습니다.특정 기술에 종속된 에러가 터짐 (JDBC, JPA, Hibernate, JDO)모두 CheckedException이라 불편함특정 에러를 처리하고 싶으면 에러 코드를 직접 다뤄야 함 🐜 1 - 특정 기술에 종속된 에러가 터짐 (JDBC, JPA, Hibernate, JDO)JDBC를 열심히 쓰고 있어서 코드 곳곳에 SQLException을 처리하고 있었는데 갑자기 JPA를 도입하고자 하면 어떻게 될까요? JPA는 SQLException을 던지지 않고 PersistenceException을 던집니다. 그럼 SQLException을 쓴 모든 곳에 이걸 PersistenceException으로 바.. 2024. 5. 7.
Spring에서 Transaction 관리하는 법 알아보기 Spring에서 Transaction 관리하는 법 알아보기 기존 Transaction의 문제점🐜 Transaction을 위한 코드가 너무 많이 필요함사실 Transaction은 핵심 Business Logic이 아니기 때문에 알아서 해 줬으면 좋겠는데, Transaction을 직접 관리할 경우 이것만을 위한 코드가 너무 많이 필요합니다. public void placeOrder(Order order) { // Transaction의 속성을 만들고 TransactionDefinition transactionDefinition = new DefaultTransactionDefinition(); // 새로운 Transaction을 시작하고 TransactionStatus transactionStatus = transactionManager.ge.. 2024. 5. 6.
JDBC, 필요한 만큼만 알아보기 JDBC, 필요한 만큼만 알아보기 JDBC, 뭐 하는 거야?JDBC (Java Database Connectivity)는 Java에서 DB에 연결하기 위한 API입니다. 조금이라도 복잡하고 유용한 Application을 만들려면 DB에 연결하는게 필수인데 이를 위해서는 크게 다음과 같은 과정을 따릅니다.DB와 연결 (TCP/IP를 맺고, 암호화 정보 전달하고 등)SQL문 전달(필요하다면) Transaction 처리결과를 받아서 처리 문제는 이 과정이 DB 마다 모두 조금씩 다르다는 겁니다... 새로운 DB를 쓸 때 마다 각 DB의 특성을 공부해서 이 과정을 진행해야 한다면 지옥이 따로 없겠죠? 그렇기 때문에 JDBC라는 표준 API를 제공하고, 각 DB가 이 JDBC를 구현해서 개발자는 JDBC의 사용법만 알면 Application에서 .. 2024. 5. 5.
도메인 모델 풍부하게 만들기 도메인 모델 풍부하게 만들기 문제의 근원 : Fat Service애초에 왜 도메인 모델을 풍부하게 만들어야 할까요? 도메인 모델을 풍부하게 만든다가 절대선이라는 생각은 일단 내려놓고 생각하면, 프로그래밍 설계에서 대부분 무언가를 해야 한다면 2가지 이유가 있습니다.더 이해하기 쉽게 만들기 위해변경에 유연하게 하기 위해 그렇다면 도메인 모델을 풍부하게 만들어야 하는 이유는 왜 때문일까요? 🤔 이건 도메인 모델이 풍부하지 않은 경우 그 로직이 어디에 가는지 생각해 보면 됩니다. 요구사항을 만족시키는 로직은 결국 어딘가에는 있어야 합니다. 보통 도메인 모델에 로직이 없다면, 서비스 계층에 있겠죠? 사실 처음에는 서비스 계층이 통통해도 괜찮습니다. 괜히 이해하기 어려운 패턴이나 아키텍처를 도입하면 이해하기만 어렵고 이득보다 손해가 많습니.. 2024. 5. 4.
Spring의 @Controller, @Repository, @Service, @Component 등 알아보기 Spring의 @Controller, @Repository, @Service, @Component 등 알아보기 스테리오타입 어노테이션 (Sterotype Annotation) 이란?Spring에서는 @로 시작하는 Annotation을 굉장히 많이 사용합니다.Annotation을 많이 사용하기 때문에 여러개를 동시에 쓰는 상황이 반복되거나, 기존 어노테이션의 동작을 약간 수정하면서도 비슷한 역할을 하는 새로운 어노테이션을 만들어야 하는 상황이 발생할 수 있습니다.이 경우에 여러개의 Annotation을 합쳐 스테리오타입 어노테이션 (Sterotype Annotation)을 만들 수 있습니다.스테리오타입 어노테이션 (Sterotype Annotation)을 사용하면 여러 개의 어노테이션을 적용해야 하는 상황을 단순화 하기 때문에 코드의 유지보수성을 높일 수 있습니다. Spring Bean을 만드는 스테리오타입 어노테.. 2024. 5. 1.
트랜잭션 전파 (Transaction Propagation) - Transaction이 서로 만날 때 스프링은 어떻게 처리할까? 트랜잭션 전파 (Transaction Propagation) - Transaction이 서로 만날 때 스프링은 어떻게 처리할까? 트랜잭션 (Transaction)이 뭔지 간단히쉽게 말해서 여러 개의 다른 동작들을 1개로 묶는 역할을 합니다. 그래서 여러 개의 동작 중에 1개라도 실패하면 다 실패해야 해서 성공한 동작도 실패로 되돌릴 수 있는 기능인 롤백 (Rollback)이 상당히 중요한 역할을 합니다.여기서 큰 그림에서 트랜잭션을 바라보면 비즈니스 로직에서 필요한 여러 동작을 하나로 묶는 것처럼 생각할 수 있는데요. 이걸 논리적 트랜잭션 (Logical Transaction)이라고 합니다. 그 반대는 당연히 물리적 트랜잭션 (Physical Transaction)이겠죠? 무슨 말이냐 하면, 송금을 생각해 보겠습니다. 논리적 트랜잭션 관점에서 큰 그림으로 보면 아래의 동작들을 1개의 트랜잭션으로 묶는 것으로 생각할 수 있습니다.송.. 2024. 3. 7.
무중단, 카나리 배포 환경에서 DB Schema 수정하기 무중단, 카나리 배포 환경에서 DB Schema 수정하기 문제 상황자주 있는 상황은 아니지만 DB의 Column을 수정해야 할 일이 있습니다.굳이 왜 수정해야 하나? 어차피 이름만 다른거 아니야? 하실 수 있지만 이름과 사용 용도가 다르면 장기적으로는 인지 비용이 높아져 팀 전체의 자원이 더 많이 들게 됩니다.무중단의 핵심은 이 작업으로 인해 에러를 만나는 유저가 1명도 없어야 한다는 것입니다.그럼 가장 먼저 떠올리는게 DB Column 변경과 배포를 딸깍딸깍 동시에 진행하면 되지 않을까 생각할 수 있습니다. 솔직히, 팀 리소스가 부족한 상황에서는 좋은 해결책이라 생각합니다. 새벽 시간 트레픽이 없을 때를 틈타 작업하면 큰 문제가 없을 수도 있습니다.하지만 서비스의 중요도가 높거나 카나리 배포를 하고 있는 환경에서는 이것도 어렵습니다. 이 상황에서 정말 무중단.. 2024. 2. 25.
다양한 로그인 방법을 알아보자 (OAuth, Open ID, OIDC, SSO, SFA, 2FA, MFA, OTP, PassKey) 다양한 로그인 방법을 알아보자 (OAuth, Open ID, OIDC, SSO, SFA, 2FA, MFA, OTP, PassKey) 🐜 큰 그림우선, 로그인이란 나만 아는 정보를 제공해서 모두가 접근할 수 없는 특정 정보를 접근하는 것을 말합니다. 당연히 보안이 좋기 위해서는 나만 알 수 있는 정보들을 최대한 많이 제공하는게 좋겠죠. 하지만 로그인 할 때 마다 아이디/비밀번호를 입력하고, 지문이나 얼굴 인증을 하고, OTP 코드를 입력한다면 너무 불편해서 거의 쓰지 않겠죠? 그래서 보안과 편의성 사이의 저울질이 중요합니다.🐜 분류하기SFA, 2FA, MFA = 1번만 인증을 하냐, 여러번 인증을 하냐? 로그인 할 때 아이디/비밀번호든, 생체인증 (얼굴, 지문 등)이든, 1개의 인증정보만 제공하면 SFA (Single Factor Authentication)입니다. 여기에 더해 추가로 흔하게는 OTP (One-Time Passwor.. 2024. 2. 8.
Kotlin Sequence (스퀸스) 에 대해 알아보자 Kotlin Sequence (스퀸스) 에 대해 알아보자 🐜 Sequence, 본질적으로 뭘까?Type Kotlin의 Sequence는 Type입니다. Collection 처럼 값을 담고 있지만 Eager하게 만드는게 아닌 Lazy하게 만들어 대량의 데이터를 효율적으로 다루거나 무한히 계속되는 데이터를 다룰 수 있게 해 줍니다.예를들어 아래와 같이 특정 연산을 하고 난 결과의 1번째 값을 가져오는 코드가 있다고 해 봅시다.(100 until 2_000_000) .map { it * 2 } .filter { it % 3 == 0 } .first() 이 코드의 내부 동작을 살펴보면 우선 map으로 모든 원소를 2배 한 후, filter로 모든 원소의 나머지를 계산해 0인 원소만 남긴 뒤, 여기서 첫 번째 원소를 가져옵니다. Eager 하게 동작하기 때문에 이런식.. 2024. 2. 4.
핵사고날? 클린 아키텍처? DDD? 핵사고날? 클린 아키텍처? DDD? 🐜 취준생들의 단골멘트취준생들의 이력서에 단골로 등장하는 단어가 있습니다. 이름도 멋진 헥사고날 Architecture입니다.처음 헥사고날 Architecture류의 용어들 (헥사고날 Architecture, DDD, Clean Architecture)를 접했을 때 저는 쓸데없이 복잡하고 혼란스러운 이것들을 왜 써야 하는지 도저히 이해할 수가 없었습니다.그도 그럴게, 헥사고날 Architecture가 왜 좋은지 알려면 Business Logic이 꽤 복잡한 애플리케이션을 다뤄야 하기 때문입니다. 간단한 CRUD 애플리케이션에 핵사고날 아키텍처를 써 봤자 쓸데없이 복잡할 뿐이죠.그럼 헥사고날 Architecture가 왜 태어났고 왜 유용한지 여태까지 이해하고 경험한 내용들을 써 보겠습니다.🐜 용어부터 .. 2024. 1. 28.
CQRS (Command Query Responsibility Segregation) 알아보기 CQRS (Command Query Responsibility Segregation) 알아보기 CQRS(Command Query Responsibility Segregation)가 뭔데CQRS는 영어 줄임말 그대로 Command와 Query를 분리한다는 개념입니다. Command가 뭐고, Query는 또 뭐고, 왜 분리해야 할까요?Query - 읽는 동작입니다. 읽기만 할 뿐 데이터나 상태를 절대 변경시키면 안 됩니다.Command - 변경하는 동작입니다. 보통 내부 상태나 데이터를 구체적으로 어떻게 변경할지는 명시하지 않고 도메인에 맞는 동작을 전해주는 경우가 많습니다.여기서 Command에 대해 자세히 알아봅시다! Command가 상태를 변경한다고 해도 이를 명시적으로 하면 결국 어떤 동작을 해야 할지 각각의 도메인에 가서 다 확인해야 합니다. 예를들어 배송 시스템이 있다고 하고 유저가 주문을.. 2023. 12. 8.
반응형