본문 바로가기

Programing

(405)
Electron ≥ 12.x : 컨텍스트 분리(Context Isolation) 3년전에 둘째 출산 휴가 때 진행했던 serami 프로젝트를 얼마 전에 다시 보게 되었다. 이메일 인증을 개발하면서 템플릿의 결과를 확인하게 위해 사용을 했는데 개발한지 오래되었다보니 Github에서 버전 업데이트에 대한 경고를 그 동안 지속적으로 받고 있었다. 라이브러리 업데이트를 하고나서 보니 "Uncaught ReferenceError: require is not defined" 에러가 발생했다. 에러의 부분을 찾아보니 리액트를 bootstrap 하는 부분인 require 이라는 부분에 문제가 발생하였다. 일단 찾아보니 Electron 12 부터 Context Isolation 이라는 것이 활성화 되었고 Renderer Process 에서 수행할 수 있는 것들이 제한이 생겼다. stackoverfl..
[WebFlux] block()/blockFirst()/blockLast() are blocking, which is not supported in thread 후기 백엔드를 개발하다가 이제 회원 백엔드를 맡으면서 Spring WebFlux를 다루게 되었다. 아직 Reactive Stack에 대한 경험이 부족해서 도메인 객체를 포함해서 DB연결 및 Redis 연결을 동기식으로 처리를 했다. 그런데 이전에 개발된 회원 번호에 대한 유효성 확인을 하는 함수가 Mono 를 반환하게 되어 있었다. 어디서 들은 지식으로 block()을 이용해서 블로킹 처리를 하려고 했더니 아래와 같은 에러 메시지가 발생했다. block()/blockFirst()/blockLast() are blocking, which is not supported in thread reactor-http-nio-2 누가 이렇게 에러를 던지나 찾아보았다. Mono의 block()은 아래와 같이 구현되어 ..
Spring Boot: JPA(Hibernate) 네이밍 전략 spring.jpa.hibernate.naming.physical-strategy 및 spring.jpa.hibernate.naming.implicit-strategy 을 통해 테이블 이름이나 컬럼 이름에 대한 네이밍 전략 설정이 가능하다. 네이밍 컨벤션에는 여러가지가 있다. camelCase: 앞자는 소문자 단어 사이에 대문자 PascalCase: camleCase와 같은데 첫 글자가 대문자이다. Initial Capitals, Initial Caps, InitCaps 로도 불린다. snake_case: 모든 문자는 소문자(lowercase)로 단어간 구분은 언더스코어(_)로 구분한다. kebab-case: 모든 문자는 소문자(lowercase)로 단어간 구분은 대시(-)로 구분한다. ALL CAPS:..
ServletModelAttributeMethodProcessor 와 @PathVariable ServletModelAttributeMethodProcessor 은 ModelAttributeMethodProcessor 상속받아 서블릿을 위한 위한 구현체이다. 가령 Spring MVC 에서 @PathVariable 을 이용해 URI 템플릿을 파라미터로 받아올 때 ServletModelAttributeMethodProcessor 가 사용된다. 사례 예로 아래와 같은 코드가 있을 때 requestNo 과 memberNo 에는 URI path의 템플릿 값이 들어오게 된다. @RestController public class VPNController { @GetMapping(value = "/vpn/{memberNo}/{requestNo}", produces = MediaType.APPLICATION_JS..
@NotNull이 Needs Work가 필요한 수준인가요? 코드 리뷰를 하다가 제목과 같은 질문을 받았다. @NotNull이 Needs Work가 필요한 수준인가요? 사업자등록번호에 대한 유효성 제약 수정이 있어서 PR을 받았는데 의견을 남기고 추가적인 작업이 필요할 것 같아서 Needs Work 로 마크를 했었다. 아래와 같은 요청 파라미터로 사용되는 객체이다. (실무 코드는 아니고 예제이다.) import lombok.Getter; import lombok.Setter; import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotNull; @Getter @Setter public class MemberJoinRequest implements Member { @NotN..
Spring boot: HttpMessageConverters 는 누가 만들어줄까? RestTemplate 에 대해 통합 테스트를 만드는 과정에서 HttpMessageConverters 빈이 없다고 에러가 났다. 그러면 이 HttpMessageConverters 빈은 누가 만들어주고 있었을까? 스프링 부트에는 여러 Auto Configuration 이 있는데 HttpMessageConvertersAutoConfiguration 가 해주고 있었다. package org.springframework.boot.autoconfigure.http; @Configuration @ConditionalOnClass(HttpMessageConverter.class) @AutoConfigureAfter({ GsonAutoConfiguration.class, JacksonAutoConfiguration.c..
Kotlin DSL Gradle: 멀티 모듈로 변경하기 단일 모듈 기반의 프로젝트 spring initializr 에서 프로젝트를 만들면 기본적으로 단일 모듈 기반의 프로젝트를 생성한다. 이 구조는 단순하고 만들기 쉽지만 단점도 있다. 핵심 비즈니스 구현을 하는 도메인 영역과 세부사항의 일종인 구현 기술의 코드가 섞이게 되기 때문이다. 실무를 하면서 일종의 기술 영역인 JPA의 Entity 가 도메인 영역인 서비스를 통과해 Controller 까지 전달했던 것을 본 적이 있다. 물론 자바나 코틀린에서는 패키지를 구분하여 모듈을 분리할 수 있는 구조를 제공한다. 하지만 이것은 구조화적인 것으로 의존성에 대해 직접적인 통제를 할 수 없다. 페리페리크 안티 패턴(Périphérique anti-pattern) 헥사고날 아키텍처 - 혹은 '포트와 어댑터' - 라는 ..
DataIntegrityViolationException Sentry 로 알림이 오면 팀에서는 습관적으로 ignore 처리를 하는 것을 발견했다. 특히 배포 직후에는 이런 ignore가 빈번했는데 새로운 버전이 배포가 되면 기존의 custom ignore가 무효화가 되는 것 같았다. 백로그의 티켓 중 내부 개선 에픽이 붙어있는 묵혀놓은 티켓을 발견했다. 바로 "정상적인 케이스의 알람을 받지 않는다."이다. 위의 알람의 경우 사용자가 입력을 짧은 시간에 여러번 하여 save 명령이 두 번이 된 경우에 주로 발생했다. DB에는 UC(Unique Constraint) 조건이 달려있었기에 나중에 요청이 온 쿼리가 수행이 되지 않는다. 버튼을 클릭 후 disable로 변경시켜 입력을 두 번하는 것을 막는 것이 근본적인 방향이겠지만 해당 UI는 다른 팀이 담당하고 있어서..