Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,12 @@ repositories {
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-validation'

compileOnly 'org.projectlombok:lombok'
runtimeOnly 'mysql:mysql-connector-java:8.0.33'
annotationProcessor 'org.projectlombok:lombok'

testImplementation 'org.springframework.boot:spring-boot-starter-test'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
}
Expand Down
1 change: 0 additions & 1 deletion build/resources/main/application.properties

This file was deleted.

34 changes: 34 additions & 0 deletions src/main/java/com/m0omoo/demo/controller/UserController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package com.m0omoo.demo.controller;

import com.m0omoo.demo.dto.SignUpRequest;
import com.m0omoo.demo.service.UserService;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

/**
* 회원 관련 HTTP 요청을 처리하는 컨트롤러 클래스
* 클라이언트의 요청을 받아 서비스 로직을 호출한 뒤, 응답을 반환하는 역할
*/
@RestController // 해당 클래스가 REST API 요청을 처리하는 컨트롤러임을 선언
@RequiredArgsConstructor // final 필드를 자동으로 생성자 주입하는 Lombok 어노테이션
@RequestMapping("/api/v1/users") // 이 컨트롤러 내 모든 요청의 기본 경로 설정
public class UserController {

// 회원 관련 비즈니스 로직을 처리하는 서비스 의존성
private final UserService userService;

/**
* 회원가입 요청 처리 핸들러
* HTTP POST 방식으로 /signup 경로에 들어온 요청을 처리
* 요청 본문에는 SignUpRequest 형태의 JSON 데이터 포함
*
* @param request 클라이언트로부터 받은 회원가입 요청 DTO
* @return 성공 메시지를 담은 HTTP 응답
*/
@PostMapping("/signup")
public ResponseEntity<?> signUp(@RequestBody SignUpRequest request) {
userService.register(request); // 회원가입 처리 수행
return ResponseEntity.ok("회원가입 성공"); // 성공 메시지 반환
}
}
36 changes: 36 additions & 0 deletions src/main/java/com/m0omoo/demo/domain/User.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package com.m0omoo.demo.domain;

// JPA 관련 어노테이션들을 불러
import jakarta.persistence.*;

// Lombok 어노테이션: 반복되는 코드 생성을 줄여
import lombok.*;

/**
* User 엔티티 클래스
* 이 클래스는 데이터베이스 테이블과 매핑되는 객체
*/
@Entity // 이 클래스가 JPA의 엔티티임을 나타냄. 즉, DB 테이블로 매핑
@Getter // Lombok: 모든 필드의 Getter 메서드를 자동 생성
@Setter // Lombok: 모든 필드의 Setter 메서드를 자동 생성
@NoArgsConstructor // Lombok: 파라미터가 없는 기본 생성자를 생성
@AllArgsConstructor // Lombok: 모든 필드를 매개변수로 받는 생성자를 생성
@Builder // Lombok: 객체를 쉽게 생성할 수 있는 빌더 패턴을 자동으로 생성
public class User {

@Id // 이 필드가 테이블의 기본 키(PK)라는 것을 명시
@GeneratedValue(strategy = GenerationType.IDENTITY)
// 기본 키를 DB가 자동으로 생성하게 함 (보통 AUTO_INCREMENT처럼)
private Long id;

@Column(nullable = false, unique = true)
// DB 컬럼: null을 허용하지 않으며, 중복을 허용하지 않음 (이메일은 고유해야 하므로)
private String email;

@Column(nullable = false)
// DB 컬럼: null을 허용하지 않음 (비밀번호는 반드시 입력되어야 함)
private String password;

// 닉네임은 null 가능. 특별한 제약 조건이 없기 때문에 @Column 생략
private String nickname;
}
28 changes: 28 additions & 0 deletions src/main/java/com/m0omoo/demo/dto/SignUpRequest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package com.m0omoo.demo.dto;

import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.NotBlank;
import lombok.Getter;
import lombok.Setter;
/**
* 회원가입 요청 데이터를 담는 DTO 클래스
* 클라이언트가 전달한 이메일, 비밀번호, 닉네임 정보를 담는 용도
* 컨트롤러 → 서비스로 데이터를 전달할 때 사용하는 중간 객체
*/
@Getter // 각 필드에 대한 Getter 메서드 자동 생성 (예: getEmail())
@Setter // 각 필드에 대한 Setter 메서드 자동 생성 (예: setEmail())
public class SignUpRequest {

// 사용자 이메일 정보
@NotBlank(message = "이메일은 필수 입력입니다.")
@Email(message = "올바른 이메일 형식이 아닙니다.")
private String email;

// 사용자 비밀번호 정보
@NotBlank(message = "비밀번호는 필수 입력입니다.")
private String password;

// 사용자 닉네임 정보
@NotBlank(message = "닉네임은 필수 입력입니다.")
private String nickname;
}
19 changes: 19 additions & 0 deletions src/main/java/com/m0omoo/demo/repository/UserRepository.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.m0omoo.demo.repository;

import com.m0omoo.demo.domain.User;
import org.springframework.data.jpa.repository.JpaRepository;

import java.util.Optional;

/**
* User 엔티티와 관련된 데이터베이스 접근 기능 정의 인터페이스
* Spring Data JPA에서 제공하는 JpaRepository를 상속하여 기본적인 CRUD 기능 제공
*/
public interface UserRepository extends JpaRepository<User, Long> {

/**
* 이메일을 기준으로 사용자 정보를 조회하는 메서드
* 반환값은 Optional<User> 형태로, 값이 없을 경우를 안전하게 처리할 수 있음
*/
Optional<User> findByEmail(String email);
}
40 changes: 40 additions & 0 deletions src/main/java/com/m0omoo/demo/service/UserService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package com.m0omoo.demo.service;

import com.m0omoo.demo.domain.User;
import com.m0omoo.demo.dto.SignUpRequest;
import com.m0omoo.demo.repository.UserRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

/**
* 사용자 관련 비즈니스 로직을 처리하는 서비스 클래스
* 회원가입 로직을 중심으로 구현
*/
@Service
@RequiredArgsConstructor
public class UserService {

// User 엔티티에 접근하기 위한 JPA 리포지토리 의존성 주입
private final UserRepository userRepository;

/**
* 회원가입 처리 로직
* 이메일 중복 여부 확인 후 사용자 엔티티 저장
*/
public void register(SignUpRequest dto) {
// 이메일 중복 여부 확인
if (userRepository.findByEmail(dto.getEmail()).isPresent()) {
throw new IllegalArgumentException("이미 존재하는 이메일");
}

// 전달받은 DTO를 기반으로 User 엔티티 생성
User user = User.builder()
.email(dto.getEmail())
.password(dto.getPassword()) // 추후 비밀번호 암호화 필요
.nickname(dto.getNickname())
.build();

// DB에 사용자 정보 저장
userRepository.save(user);
}
}