Skip to content

Commit

Permalink
Merge pull request #1 from BE-04-JTOON/refactor/multi-module
Browse files Browse the repository at this point in the history
refactor: multi module 모듈 재정의
  • Loading branch information
parksey committed Apr 17, 2024
2 parents cca735a + 3ec0ca8 commit 7b543ba
Show file tree
Hide file tree
Showing 232 changed files with 2,416 additions and 3,283 deletions.
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -121,3 +121,8 @@ gradle-app.setting
application-*.yml
!application.yml
!application-test.yml

smtp.yml
redis.yml
db-main.yml
logging.yml
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[submodule "jtoon-core/core-api/src/main/resources/config"]
path = jtoon-core/core-api/src/main/resources/config
url = https://github.com/BE-04-JTOON/private-env.git
69 changes: 32 additions & 37 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -1,56 +1,51 @@
buildscript {
ext {
springBootVersion = '3.1.2'
}

repositories {
mavenCentral()
}

dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
classpath "io.spring.gradle:dependency-management-plugin:1.1.2"
}
plugins {
id 'java'
id "java-library"
id 'org.springframework.boot' apply false
id 'io.spring.dependency-management' apply false
}

subprojects {
group 'shop.jtoon'
version '0.0.1-SNAPSHOT'
java.sourceCompatibility = javaVersion

apply plugin: 'java-library'
apply plugin: 'idea'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'
applicationVersion=project['applicationVersion']
projectGroup=project['projectGroup']
javaVersion=project['javaVersion']

allprojects {
group = projectGroup
version = applicationVersion

sourceCompatibility = 17
apply plugin: "java"
apply plugin: "java-library"

repositories {
mavenCentral()
maven { url 'https://jitpack.io' }
}
}

subprojects {
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'

dependencies {
// Lombok
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
}

test {
useJUnitPlatform()
// Test
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
}

project(':module-application') {
bootJar.enabled = false
}

project(':module-domain') {
bootJar.enabled = false
}
tasks.getByName('bootJar') {
enabled = false
}

project(':module-internal') {
bootJar.enabled = false
tasks.getByName("jar") {
enabled = true
}
}

project(':module-core') {
bootJar.enabled = false
}
tasks.named('test') {
useJUnitPlatform()
}
12 changes: 12 additions & 0 deletions gradle.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Project dependency versions
applicationVersion=0.0.1
javaVersion=17

# Project Configs
projectGroup=shop.jtoon


# Spring dependency versions
springBootVersion=3.2.4
springDependencyManagementVersion=1.1.4
springCloudDependenciesVersion=2023.0.1
45 changes: 45 additions & 0 deletions jtoon-core/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# JToon Core

Jtoon 서비스의 해결하고자하는 도메인에 대한 모듈

## 계층별 지키고자 하는 조건
(layered 기반)

- Presentation Layer : 외부 의존성이 높은 영역, Controller, dto 존재
- Domain Layer(Service) : 해결하고자 하는 문제인 도메인에 집중하고자 하는 layer
- Repository Layer : 상세 구현 로직이 다양한 자원에 접근할 수 있는 기능을 제공하는 레이어

## Include

### 초기
- `core-api`: 전체 도메인 로직에 대한 모듈만 존재

단점:
1. 모든 기능이 해당 모듈에 몰려있어서 많은 의존성을 가지고 있다.
2. 도메인은 문제를 해결하기 위한 영역이기 때문에 외부의 의존성을 가지는 것이 맞을까?
3. Batch서버를 따로 올린다고 했을 때, Runnable한 API가 2개가 생기게 되는데 이때 동일한 도메인 기능을 서로 다르게 관리하게 된다.

## 2번째 리팩토링

### Core API
Presentation 영역, 외부 의존성이 높다.

- Controller, Dto가 존재
- 확장되지 않는 서비스에 대한 로직 예를들어 Admin은 여기에 추가하고 추후에 변경

### Core domain
오직 Domain 서비스만 관리하는 모듈

- Domain서 서비스를 문제만 해결하기 위해 spring framework의 의존성을 없애는 것으로 한다.
- spring framework가 자체적으로 변경되든, framework를 변경할때 domain 로직이 변경되는 것이 옳지 않다고 생각
- 단 DB가 존재하기 때문에, JPA는 추가

#### 문제
- Bean등록을 어떻게 하면 좋을까?
- Transaction은 어떻게 해야할까


이렇게하면, 여러 개의 Runnable한 서비스가 가능하다

단점:
- 도메인이 DB에 의존적이다. 근데 DB를 변경하는 경우가 많을까? 에 대한 생각을 해볼 필요가 있다.
48 changes: 48 additions & 0 deletions jtoon-core/core-api/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
tasks.getByName('bootJar') {
enabled = true
}

tasks.getByName("jar") {
enabled = false
}

dependencies {

implementation project(":jtoon-core:core-domain")

implementation project(":jtoon-internal:core-web")
implementation project(":jtoon-internal:iamport-client")
implementation project(":jtoon-internal:s3-client")
implementation project(":jtoon-internal:smtp-client")

implementation project(":jtoon-support:logging")
implementation project(":jtoon-support:monitoring")

implementation project(":jtoon-system")

implementation project(":jtoon-db:db-redis")

// Web
implementation 'org.springframework.boot:spring-boot-starter-web'

// Bean Validation
implementation 'org.springframework.boot:spring-boot-starter-validation'

// AOP
implementation 'org.springframework.boot:spring-boot-starter-aop'

// Security
implementation 'org.springframework.boot:spring-boot-starter-security'
testImplementation 'org.springframework.security:spring-security-test'

// OAuth2
implementation 'org.springframework.boot:spring-boot-starter-oauth2-client'

// JWT
implementation 'io.jsonwebtoken:jjwt-api:0.11.5'
runtimeOnly 'io.jsonwebtoken:jjwt-impl:0.11.5'
runtimeOnly 'io.jsonwebtoken:jjwt-jackson:0.11.5'

// RestDocs
testImplementation 'org.springframework.restdocs:spring-restdocs-mockmvc'
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package shop.jtoon.global.aop;

import lombok.extern.slf4j.Slf4j;
import java.lang.reflect.Method;
import java.util.Arrays;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.AfterReturning;
Expand All @@ -10,8 +12,7 @@
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.util.Arrays;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@Aspect
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package shop.jtoon.member.application;

import org.springframework.stereotype.Service;

import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import shop.jtoon.login.service.LoginDomainService;
import shop.jtoon.member.domain.MyInfo;
import shop.jtoon.member.dto.OAuthSignUpDto;
import shop.jtoon.member.entity.Member;
import shop.jtoon.member.request.LocalSignUpReq;
import shop.jtoon.security.request.LoginReq;
import shop.jtoon.security.service.JwtService;
import shop.jtoon.security.service.RefreshTokenService;
import shop.jtoon.security.util.TokenCookie;
import shop.jtoon.util.SecurityConstant;

@Service
@RequiredArgsConstructor
public class LoginService {

private final JwtService jwtProvider;
private final RefreshTokenService refreshTokenServiceImpl;

private final LoginDomainService loginService;

public void signUp(LocalSignUpReq localSignUpReq) {
loginService.signUp(localSignUpReq.toLoginInfo(), localSignUpReq.toUserInfo());
}

public void loginMember(LoginReq loginReq, HttpServletResponse response) {
loginService.login(loginReq.toLoginInfo());

String accessToken = jwtProvider.generateAccessToken(loginReq.email());
String refreshToken = jwtProvider.generateRefreshToken();
refreshTokenServiceImpl.saveRefreshToken(refreshToken, loginReq.email());

response.addCookie(TokenCookie.of(SecurityConstant.ACCESS_TOKEN_HEADER, accessToken));
response.addCookie(TokenCookie.of(SecurityConstant.REFRESH_TOKEN_HEADER, refreshToken));
}

public Member generateOrGetSocialMember(OAuthSignUpDto oAuthSignUpDto) {
return loginService.generateOrGetSocialMember(oAuthSignUpDto.toLoginInfo(), oAuthSignUpDto.toUserInfo());
}

public MyInfo readMyInfo(String email) {
return loginService.findMemberDtoByEmail(email);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package shop.jtoon.member.dto;

import lombok.Builder;
import shop.jtoon.member.domain.MyInfo;
import shop.jtoon.member.entity.Gender;
import shop.jtoon.member.entity.Role;

@Builder
public record MemberDto(
Long id,
String email,
String name,
String nickname,
Gender gender,
Role role,
String phone
) {
public static MemberDto toDto(MyInfo myInfo) {
return MemberDto.builder()
.id(myInfo.id())
.email(myInfo.email())
.name(myInfo.name())
.nickname(myInfo.nickname())
.gender(myInfo.gender())
.role(myInfo.role())
.phone(myInfo.phone())
.build();
}
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
package shop.jtoon.dto;
package shop.jtoon.member.dto;

import static shop.jtoon.type.ErrorStatus.*;

import java.util.Map;
import java.util.UUID;

import lombok.AccessLevel;
import lombok.Builder;
import shop.jtoon.entity.LoginType;
import shop.jtoon.exception.InvalidRequestException;
import shop.jtoon.member.entity.LoginType;

@Builder(access = AccessLevel.PRIVATE)
public record OAuthAttributes(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package shop.jtoon.member.dto;

import lombok.Builder;

import shop.jtoon.login.domain.LoginInfo;
import shop.jtoon.login.domain.UserInfo;
import shop.jtoon.member.entity.Gender;
import shop.jtoon.member.entity.LoginType;

@Builder
public record OAuthSignUpDto(
String email,
String password,
String name,
String nickname,
String gender,
String phone,
String loginType
) {
public LoginInfo toLoginInfo() {
return LoginInfo.builder()
.email(email)
.password(password)
.loginType(LoginType.from(loginType))
.build();
}

public UserInfo toUserInfo() {
return UserInfo.builder()
.name(name)
.nickname(nickname)
.gender(Gender.from(gender))
.phone(phone)
.build();
}
}
Loading

0 comments on commit 7b543ba

Please sign in to comment.