프로젝트 39

처음 테스트 코드를 작성하며 겪었던 문제들

spring boot의 controller 클래스의 테스트 코드를 만들어봤다. 이게 내 첫 테스트 코드 경험이다. mockito 쓰는 게 아직 낯설지만 테스트 코드를 작성하다 만났던 에러들을 기록한다. @WebMvcTest(UserApiController.class) class UserApiControllerTest { @Autowired private MockMvc mvc; @MockBean private UserService userService; private Gson gson = new Gson(); ... } 테스트 케이스 위에 @WebMvcTest 를 써주는 것만으로도 무사히 테스트가 통과됐다. 처음에는 검색 시 너무 많은 애노테이션이 나와서 이것저것 다 써봤는데 이거 하나면 충분했다. 주의할..

사용자 스토리로 요구사항 정리해보기

프로젝트 개발에 무작정 돌입했지만 요구사항을 한번 싹 정리해놓고 개발하는 게 좋겠다는 생각이 들었다. 기능을 하나 개발하고 보니 추가적으로 필요한 매개변수가 생각나는 문제점이 존재해 이런 생각에 이르렀다. 그리고 다음에는 무엇을 개발해야 할 지 생각하는 게 조금 오래 걸리는 감이 있어서 요구사항 정리의 필요성을 느꼈다. 스프링 5와 vue.js2로 시작하는 모던 웹 애플리케이션 개발 책을 보고 있는데 요구사항 분석부터 데이터 모델링, 코드 설계, api 설계, 개발, 배포까지 전 과정을 정리해 놓은 좋은 리소스이다. 백엔드 개발을 공부할 때 많이 보게 됐던 디자인 패턴과 용어들을 잘 정리해준 책이다. 이 포스트에서는 사용자 스토리로 요구사항을 작성하는 부분을 내 프로젝트에 적용해보았다. 사용자 스토리란 ..

AService에서는 ARepository만 사용하고 BService 사용은 지양하자

처음에 하나의 엔티티 타입을 위한 서비스 클래스를 만들 때 다른 엔티티 타입의 서비스 클래스도 막 가져와서 사용했었다. 이렇게 여러개가 만들어지다 보니 어디에서 썼는지 기억도 잘 안 나고 코드가 너무 지저분해 보였다. 또 단일 책임 원칙도 약간 빗겨간 느낌이 들었다. 초반의 더러운 코드 - 여러 다른 서비스를 주입 받아 사용하고 있다. @Service @RequiredArgsConstructor @Transactional(readOnly = true) public class ProjectService { private final ProjectRepository projectRepository; private final PartService partService; private final UserPartS..

단일 테이블 전략에 의해 자동으로 생성된 칼럼인 dtype을 get하고 싶으면

기술 스택들이 저장되는 Stack 테이블에서 데이터를 모두 가져와야 하는 상황이다. 데이터가 많지 않기 때문에 페이지네이션도 필요없고 정말 한 번에 다 가져와도 문제가 없을 양이다. 단일 테이블 전략에 의해 자동으로 생성된 칼럼인 dtype을 get한다. 그 뒤 프론트엔드 쪽에서 dtype별로 다른 div 아래에 데이터를 그려주기를 원했다. 그러면 쿼리를 한번만 날려서 테이블에 있는 데이터를 전부 한 번에 가져올 수 있기 때문이다. 문제는 이 dtype이 자동으로 생성됐기 때문에 lombok으로 @Getter를 선언해도 getDtype()은 만들어지지 않는다. 그래서 Stack 엔티티에 dtype 필드를 추가해줘봤다. 자동으로 만들어주는 dtype과 중복이기 때문에 충돌이 나 에러를 내주는 것을 볼 수 ..

Entity 설계하기

백엔드에 있어서 데이터베이스의 설계는 중요하다. 효율적으로 설계하기는 쉽지 않지만 김영한 님의 스프링 강의에서 봤던 엔터티 관계를 떠올리며 만들어봤다. draw.io가 제약이 적은 무료 툴이라 사용했는데 left spacing이 작동하지 않는다. 그래서 엔티티의 필드를 볼 때 가독성이 떨어진다. 김영한 님의 spirng 강의에서 category가 트리 구조라 자신과 관계를 맺는 엔티티였다. 그걸 반영하니 대댓글의 엔티티 관계를 만들 수 있었다. Question에 parent와 child를 둬서 parent는 대댓글의 원 댓글을, child는 대댓글들을 값으로 가질 것이다. Stack은 frontend, backend, design 3 분류 나눌 예정이기 때문에 상속 관계를 써야 한다고 생각했다. 굳이 데..

인스타그램 프로필 화면 같은 멀티 탭 만들기 - React Navigation 혹은 TabView를 ScrollView로 감싸지 마세요

React Navigation 혹은 TabView를 ScrollView로 감싸지 마세요 저는 이 행동으로 인해 오전을 날렸습니다. react native tab view의 github README에 보면 ScrollView로 감싸지 말라는 말이 있습니다. 읽어보니 최적화만 좀 안 되는 거라는 생각을 하게 됩니다. 일단 테스트니까 그냥 시도해보자고 생각할 지도 모르겠습니다. 하지만 그 순간 에러 지옥으로 빠지는 것입니다. 상단 탭바를 위해 react navigation의 material top navigator를 사용했습니다. const Tab = createMaterialTopTabNavigator(); {/* 썸네일 */} {/* 썸네일 없으면 기본 icon 표시 */} {/* 닉네임 */} {myIn..

프로젝트/튜토 2021.08.22

아찔한 리액트의 무한 요청

// 시작할 때, 프로필 편집 화면에서 뒤로 왔을 때 fetch useEffect(() => { const fetchMyInfo = async () => { try { const result = await getMyInfo(); setMyInfo(result.data); } catch (err) { alert("예상치 못한 문제가 발생했습니다."); } }; fetchMyInfo(); }); 프로필 편집 후 뒤로 왔을 때 단순히 refetch하면 간단할 것이라 생각했다. 그래서 useEffect의 두번째 인자인 업데이트 트리거 배열을 []에서 아예 없애버렸다. 그랬더니 setMyInfo에 의해 state가 변하면서 계속 useEffect 함수가 호출된다. 노트북이 뜨거워지길래 뭐지 싶었는데 서버 로그를 ..

프로젝트/튜토 2021.08.21

[리뷰집] 프로젝트 소개

크롤링 공개가 문제가 될까 하는 걱정에 도메인은 닫아둔 상태입니다. 필요성 이 프로젝트를 만든 사람은 독해력이 약합니다. 기억력도 그다지 좋지 않습니다. 그리고 돈이 많지 않아 무엇이든 하나 살 때 리뷰를 꼼꼼하게 읽어봅니다. 읽다 보면 어느새 모든 리뷰를 읽고 있습니다. 하지만 너무 많은 리뷰를 한 번에 읽었기 때문에 시간은 많이 소비했지만 머릿속에 잘 기억이 남지를 않습니다. 그 제품이 그래서 어떤 특징을 가지고 있는지, 장점은 뭔지, 단점은 뭔지 요약할 수 있어야 하는데 그게 쉽지 않습니다. 그래서 리뷰에서 자주 등장하는 단어를 뽑아내서 해당하는 문장들만 읽고 싶었습니다. 자주 등장하는 단어는 곧 그 제품의 특징을 말해줍니다. 하지만 여기에서 그치지 않고 제품의 장점을 대표하는 단어, 단점을 대표하..

PyKomoran 사용법 정리

PyKomoran github 페이지에 사용법을 확인할 수 있게 링크가 걸려있다. 그런데 링크를 눌러보면 서버가 망가진 건지 도메인 갱신을 안 하신 건지 페이지 오류가 떠서 확인할 수가 없다. PyKomoran 덕분에 프로젝트를 성공적으로 배포할 수 있었기 때문에 PyKomoran 함수들에 대해 정리 해본다. PyKomoran install pip install PyKomoran 대문자, 소문자가 섞여있으니 주의가 필요하다 import from PyKomoran import Komoran, DEFAULT_MODEL 보통은 이 두가지만 import 하면 문제 없이 사용 가능할 것이다. 생성자 komoran = Komoran(DEFAULT_MODEL['LIGHT']) 이와 같이 LIGHT 모델을 사용하는 k..

python 메모리와의 전쟁[종지부] - konlpy를 버리고 PyKomoran을 선택하다

정말 나의 리뷰 프로젝트를 heroku 무료 서버에 올리기 힘들었다. 메모리 개선만을 위해 거의 일주일을 불태웠다. 저장 용량은 단 500MB만 허락되는데 konlpy, django를 비롯해 꼭 필요한 패키지들과 RNN 학습 모델, 토크나이저 등 꼭 필요한 파일들만 heroku에 올렸을 때 497.8MB로 간당간당하게 올라갔었다. 하지만 메모리 제한에 막혔었다. heroku 무료 서버 기준 512MB까지 RAM을 사용할 수 있지만 1024MB까지는 ERROR R14를 띄우면서 허용해준다. worker가 죽지 않는다는 뜻이다. 1024MB를 넘어가면 ERROR R15를 띄우면서 강제 종료된다. 저장 용량부터 거의 500MB였기 때문에 쉽게 worker가 강제 종료됐다. 자연어 처리를 heroku 무료 서버..