# 테이블 별 PK (ID) 설정 시 주의점 ID는 테이블 별로 독립적으로 생성하는게 좋다 -> 서비스가 커질수록 공통으로 ID 값을 쓰면 관리하기 어렵기 때문이다. 비슷한 의미에서 ID 값은 Int 보다는 Long을 사용한다 -> Int 최대값 : 21억, Long 최대값 : 경단위. 나중에 서비스가 커지면 21억의 숫자는 나름 금방 채워지고, 이때 Int -> Long 마이그레이션 비용이 많이 발생한다. (실무팁) # 외래키의 주인은 '다' 쪽에서 관리한다 # @ManyToMany 다대다 JPA에서 다대다 옵션을 제공하긴 하지만, 실무에서는 사용하면 안 된다. 암묵적으로 테이블을 만들어줘서 관리하기 힘들기 때문이다. # 다대다 구현 일대다 + 다대일 관계로 풀어서 테이블을 설계한다. 암묵적 테이블을 ..
# 서론 사용자 요청 JSON과, REST API 서버의 경우 Response body를 로깅하고 싶은 요구사항이 생겨서 찾아보다가 구현한 방법을 정리한다. # 사전지식 - 서블릿 Reqeust, Response는 단 한번만 읽을 수 있다 로깅을 하기 위해서는 필터나 인터셉터를 통해서 서블릿 Request, Response를 접근해서 그 content를 읽어야한다. 그런데 그냥 읽으면 컨트롤러에서 해당 요청을 처리 못 한다. (아마 예외를 맞이할 것이다.) 이는 서블릿 구조상 생기는 문제인데, 서블릿은 요청 응답 객체를 단 한번만 읽을 수 있도록 설계되어 있기 때문이다. 그래서 로깅을 위해서 Reqeust, Response 객체를 여러번 읽기 위한 Wrapper 클래스로 한번 감싸주는 작업을 수행해야 한..
신규 프로젝트를 진행하면서 기존 자바 + 스프링 부트에서 코틀린 + 스프링 부트로 프로젝트를 작성해 봤다. 이를 통해서 직접 느낀 코틀린의 장단점(매우 주관적임!!)을 기록하고 공유하고자 한다. # 장점 코틀린 언어 차원에서 얻는 장점이 매우 많다. 1. 함수 파라미터에 디폴트 값 지정가능 2. 문자열 변수 연산자 $ 의 존재 3. 널 세이프 연산자들 (?, !!, ?.let 등) 4. 람다식, 함수형 프로그래밍 적극 지원 -> 함수를 일급 객체로 사용할 수 있는 점, let, apply 등 스코프 함수의 존재, 코틀린 DSL (덤으로 인텔리제이가 람다함수를 하이라이트 해주는 기능도 너무 좋다.) 6. static은 없지만, 클래스 외부에 함수 선언 가능 (사실상 static 이 필요없다.) 7. whe..
JPA Auditing 으로 생성일과 수정일을 삽입하는 용도의 super class인 BaseTimeEntity를 코틀린으로 작성하는 방법을 공유한다. 메인 어플리케이션 파일에 @EnableJpaAuditing 을 꼭 넣어줘야 한다. # 어노테이션 기반 @MappedSuperclass @EntityListeners(AuditingEntityListener::class) abstract class BaseTimeEntity1 { @CreatedDate lateinit var createTime: LocalDateTime @LastModifiedDate lateinit var updateTime: LocalDateTime } 이렇게하면 날짜 포맷팅을 지정할 순 없으나, 어노테이션으로 손 쉽게 구현이 가능하다..
# 서론 Uvicorn은 싱글 프로세스라 서비스를 실제로 할 때 서버 성능 저하가 발생할 수 있다. 그래서 해당 Uvicorn들을 여러개 관리하여 멀티프로세스 환경을 구성할 수 있도록하는 Gunicorn을 사용해서 프로세스를 여러개 구동한다. # Gunicorn 설치 pip3 install gunicorn EC2 환경에 Gunicorn을 설치한다. # Gunicorn 실행 gunicorn main:app --workers 2 --worker-class uvicorn.workers.UvicornWorker --daemon --access-logfile ./log.log --workers : 프로세스 갯수다 (최대 vcpu 갯수 * 2 만큼 설정하기를 권장) --worker-class : 프로세스를 다중으로..
# 서론 딥러닝 모델을 탑재한 백엔드 서버를 프리티어를 사용하는 인스턴스 (t2.micro) 를 통해서 배포하니까, 성능이슈가 발견되었다. (필자 로컬에서는 6초 정도 소요되는 style_transfer 모델이 EC2 에서는 무려 80초나 걸리는 문제가 있었다.) 조사해보니, vcpu랑 메모리 스펙관련 문제였다. 그래서 여러가지 EC2 인스턴스들을 바꿔가며 테스트해본 결과를 공유하고자 한다. # EC2 인스턴스 변경 방법 인스턴스 중지 후 변경하고 재시작하면 된다. 중지-시작 할 때 마다 유동 아이피가 변경된다. 이 점에 유의한다. 테스트 프로젝트 : FastAPI + NginX기반 EC2 서버, Route 53으로 DNS 매핑 그래서 새로운 인스턴스의 아이피를 계속 바꿔줘야한다. (Route 53 매핑..
서버에 파일이나 이미지를 업로드 하고 싶으면 Multipart/form-data 형식으로 HTTP 메시지를 작성해야한다. 다음은 몇 가지 주안점이다. Multipart/form-data 는 무조건 POST 요청으로 들어간다. 따라서 파일이나 이미지를 첨부한 update를 구현하고 싶으면 PUT 요청이 아닌 POST 요청으로 처리하자. Multipart/form-data는 @RequestBody가 아닌, @ModelAttribute로 받자. 만약, Resolved [org.springframework.web.HttpMediaTypeNotSupportedException: Content type 'multipart/form-data;boundary=--------------------------6513226..
인텔리제이에서 코틀린으로 스프링 부트 테스트코드를 작성하면, 가끔 리펙토링한 클래스의 이름이나 타입을 인식 못하는 버그가 있음을 발견했다. (Type Mismatch 버그) 코드 편집창에서는 빨간 밑줄이 안 생기는데, 그냥 인텔리제이 내부 문제인 것 같다. 구글링해도 해결방법이 안 나와서 이것저것 시도해보다가 찾은 해결방법을 공유하고자 글을 쓴다. Build - Gradle 에서 Build and run using 과 Run Tests using을 Gradle로 변경하고 진행한다. (인텔리제이로 설정되어 있으면 발생하는 오류인 것 같다.) Gradle 로 테스트를 돌리면 이렇게 종합 결과만 나오고 세세한 결과는 보기 어렵다. 그래서 Gradle로 빌드를 한 번 하고, 다시 인텔리제이로 바꿔서 테스트를 돌..