오랜만에 옛날 안드로이드 프로젝트를 열려고 했으나, 다음과 같은 에러 때문에 빌드가 되지 않았다. 내용을 읽어보면 두 가지 버전의 Kotlin Standard Library가 충돌된다고하는데 1.8.0과 1.6.21인가보다. 그리고 jdk8도있고 jdk7도 있다. Execution failed for task ':app:checkReleaseDuplicateClasses'. > A failure occurred while executing com.android.build.gradle.internal.tasks.CheckDuplicatesRunnable > Duplicate class kotlin.collections.jdk8.CollectionsJDK8Kt found in modules jetified-..
1. Springdoc? 1) 구성 Springdoc은 아래와 같이 구성되어있다. 그래서 타 블로그처럼 openapi-ui를 설치하게 되면, Swagger-ui까지 같이 사용하게 된다. UI를 사용하지 않아도 OpenAPI JSON이 제공된다. 그래서 코어 기능인 webmvc-core만 사용하려고 한다. UI에 관한건 Redoc을 쓰기로 했기 때문이다. 2) Default Version의 문제점 기본적으로 Spring에서 Swagger는 Description 남발은 피할수가 없다. Springdoc에서 제공하는 Example이 바로 Petstore인데 Petstore Swagger-UI로 열어보면 내용이 별로 없다는걸 알 수 있다. Front 개발자가 참고 할 만한 설명이 모두 들어가려면 @Tag, @O..
필요성의 자각 Spring 프로젝트를 백엔드 용도로 진행하면 API 문서를 작성해야만 한다. 대학에서 그렇게 논문을 쳐다보던 사람이 개발자가 되서는 문서의 효율성을 모르는 사람마냥 여기는 사람이 많더라. API 문서는 사용자의 입장에서 최대한 질문이 없도록 꼼꼼하게 써야하고, 필요한 내용이 있으면 업데이트를 해야만 한다. 프로젝트를 추후에나 혹은 새 인원이 참가하는 경우에도 인수인계를 최소한으로 할 수 있을만큼 작성되어야 한다는 것. 그리고 API 문서는 개발 진행 당시에도 중요하지만 최종 산출물이기도 하다. 좋은 API가 무엇인가를 좀 더 알고 싶다면, LINE 형님들이 쓴 글을 읽어보면 도움이 된다. 그 동안에는 어떻게 쓰였는가? 1) 문서 프로그램으로 작성 초기에는 심한경우는 Excel(물론 정리되..
시작하기에 앞서 Legacy 1, 2를 두고서 얼마나 귀찮고 힘든 과정으로 필터문을 만들어야 했는지 알아보았다. 결과적으로 SQL이 차지하는 비율은 항상 절반이 넘었다는 것을 알 수 있었다. 또한, JPA만 사용한다고 하더라도, Specification이나 Native Query를 꼭 사용해야만 하는 경우가 많았음을 보여준다. 이때까지만 하더라도 QueryDSL이 그렇게 좋아? 하는 의문이 들었다. 예전부터 QueryDSL을 쓰고 싶었으나, 내 입맛에 맞게 쓰려면 Hibernate 5, 6이나 vladmihalcea의 hibernate-types까지 나오기 전엔 못쓰겠다 싶었는데 다행히 도입하는 시점에는 입맛에 맞는 상황이 돼버린 터라 쓰게 되었다. QueryDSL을 시작하려고 다른 사람들은 어떻게 쓰고..
이번 글은 미괄식입니다. 천천히 커피 한잔 하시면서 읽어주세요 솔직히 우리는 질렸을지도 모른다. 혹은 매번 검색 필터의 결과에 대한 로직을 구성할 때마다 굉장한 절차적이고 Waterfall 같은 코드를 짜야 함에 있어서 지쳤을지도 모른다. 옛날부터 했던 코드들을 살펴보면 아래와 같다. 사실상 백엔드 개발자로서 양심을 잊었다던가, 개발을 잘 못하거나, 잘 진행하지 않거나 실패했다고 보면 된다. 대부분의 블로그 검색 코드들이나 학원에서 배운것 마냥 쓰는 코드들이나 마찬가지다 모두 실패작이다. Legacy #1 Controller Spring Framework MVC, iBatis 를 사용하던 시절에는 Controller부터 어지럽다. JSP에서 Form, 혹은 Javascript에서 FormData 형식으로..
Entity Account fads @Entity @Getter @Setter public class Account { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "id") private Long id; @Column(name = "mail", nullable = false, columnDefinition = "TEXT") private String email; @Override public String toString() { return "Account{" + "id=" + id + ", email='" + email + '\'' + ", password='" + password + '\'' + '}'; } @Colum..