From 1ccb4aa4cab2dbc2baf028d96b9024f4abc5fb56 Mon Sep 17 00:00:00 2001 From: unanchoi Date: Sat, 18 May 2024 23:29:28 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20=EC=82=AC=EC=9A=A9=EC=9E=90=20=ED=9A=8C?= =?UTF-8?q?=EC=9B=90=EA=B0=80=EC=9E=85=20API=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/message/SuccessMessage.java | 1 + .../product/controller/MemberController.java | 43 +++++++++++++++++++ .../site/sopkathon/product/domain/Member.java | 19 +++++--- .../site/sopkathon/product/dto/request/TEMP | 0 .../request/member/MemberSignUpRequest.java | 6 +++ .../site/sopkathon/product/dto/response/TEMP | 0 .../response/member/MemberSignUpResponse.java | 10 +++++ .../product/repository/MemberRepository.java | 2 + .../product/service/MemberService.java | 33 ++++++++++++++ 9 files changed, 109 insertions(+), 5 deletions(-) create mode 100644 src/main/java/site/sopkathon/product/controller/MemberController.java delete mode 100644 src/main/java/site/sopkathon/product/dto/request/TEMP create mode 100644 src/main/java/site/sopkathon/product/dto/request/member/MemberSignUpRequest.java delete mode 100644 src/main/java/site/sopkathon/product/dto/response/TEMP create mode 100644 src/main/java/site/sopkathon/product/dto/response/member/MemberSignUpResponse.java create mode 100644 src/main/java/site/sopkathon/product/service/MemberService.java diff --git a/src/main/java/site/sopkathon/product/common/message/SuccessMessage.java b/src/main/java/site/sopkathon/product/common/message/SuccessMessage.java index 512e9d0..08cc411 100644 --- a/src/main/java/site/sopkathon/product/common/message/SuccessMessage.java +++ b/src/main/java/site/sopkathon/product/common/message/SuccessMessage.java @@ -7,6 +7,7 @@ @AllArgsConstructor public enum SuccessMessage { HEALTH_CHECK_SUCCESS("Health check success"), + MEMBER_SIGN_UP_SUCCESS("Member sign up success"), TEST_IMAGE_UPLOAD_SUCCESS("Test image upload success"); private final String message; diff --git a/src/main/java/site/sopkathon/product/controller/MemberController.java b/src/main/java/site/sopkathon/product/controller/MemberController.java new file mode 100644 index 0000000..70b0b97 --- /dev/null +++ b/src/main/java/site/sopkathon/product/controller/MemberController.java @@ -0,0 +1,43 @@ +package site.sopkathon.product.controller; + + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.RequiredArgsConstructor; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import site.sopkathon.product.common.message.SuccessMessage; +import site.sopkathon.product.common.response.BaseResponse; +import site.sopkathon.product.dto.request.member.MemberSignUpRequest; +import site.sopkathon.product.dto.response.member.MemberSignUpResponse; +import site.sopkathon.product.service.MemberService; + +@RestController +@RequestMapping("/members") +@RequiredArgsConstructor +@Tag(name = "[Member API]", description = "회원 관련") +public class MemberController { + + private final MemberService memberService; + + + @Operation(summary = "회원 가입", description = "회원 가입을 진행합니다.") + @ApiResponses( + value = { + @ApiResponse(responseCode = "201", description = "회원 가입 성공") + } + ) + @PostMapping("/sign-up") + public ResponseEntity> signUp( + @RequestBody final MemberSignUpRequest request + ) { + final MemberSignUpResponse response = memberService.signUp(request); + return BaseResponse.created(SuccessMessage.MEMBER_SIGN_UP_SUCCESS, response); + } + +} diff --git a/src/main/java/site/sopkathon/product/domain/Member.java b/src/main/java/site/sopkathon/product/domain/Member.java index b12e457..9ec3efc 100644 --- a/src/main/java/site/sopkathon/product/domain/Member.java +++ b/src/main/java/site/sopkathon/product/domain/Member.java @@ -1,15 +1,24 @@ package site.sopkathon.product.domain; -import jakarta.persistence.Entity; -import jakarta.persistence.GeneratedValue; -import jakarta.persistence.GenerationType; -import jakarta.persistence.Id; +import jakarta.persistence.*; import lombok.AccessLevel; +import lombok.Builder; +import lombok.Getter; import lombok.NoArgsConstructor; +import site.sopkathon.product.common.entity.BaseTimeEntity; @Entity @NoArgsConstructor(access = AccessLevel.PROTECTED) -public class Member { +@Getter +public class Member extends BaseTimeEntity { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; + + @Column(nullable = false, unique = true, length = 50) + private String username; + + @Builder + public Member(String username) { + this.username = username; + } } diff --git a/src/main/java/site/sopkathon/product/dto/request/TEMP b/src/main/java/site/sopkathon/product/dto/request/TEMP deleted file mode 100644 index e69de29..0000000 diff --git a/src/main/java/site/sopkathon/product/dto/request/member/MemberSignUpRequest.java b/src/main/java/site/sopkathon/product/dto/request/member/MemberSignUpRequest.java new file mode 100644 index 0000000..8f4a7cf --- /dev/null +++ b/src/main/java/site/sopkathon/product/dto/request/member/MemberSignUpRequest.java @@ -0,0 +1,6 @@ +package site.sopkathon.product.dto.request.member; + +public record MemberSignUpRequest( + String username +) { +} diff --git a/src/main/java/site/sopkathon/product/dto/response/TEMP b/src/main/java/site/sopkathon/product/dto/response/TEMP deleted file mode 100644 index e69de29..0000000 diff --git a/src/main/java/site/sopkathon/product/dto/response/member/MemberSignUpResponse.java b/src/main/java/site/sopkathon/product/dto/response/member/MemberSignUpResponse.java new file mode 100644 index 0000000..7930b97 --- /dev/null +++ b/src/main/java/site/sopkathon/product/dto/response/member/MemberSignUpResponse.java @@ -0,0 +1,10 @@ +package site.sopkathon.product.dto.response.member; + +public record MemberSignUpResponse( + long userId +) { + + public static MemberSignUpResponse of(long userId) { + return new MemberSignUpResponse(userId); + } +} diff --git a/src/main/java/site/sopkathon/product/repository/MemberRepository.java b/src/main/java/site/sopkathon/product/repository/MemberRepository.java index 0de2116..21e0317 100644 --- a/src/main/java/site/sopkathon/product/repository/MemberRepository.java +++ b/src/main/java/site/sopkathon/product/repository/MemberRepository.java @@ -4,4 +4,6 @@ import site.sopkathon.product.domain.Member; public interface MemberRepository extends JpaRepository { + + boolean existsByUsername(String username); } diff --git a/src/main/java/site/sopkathon/product/service/MemberService.java b/src/main/java/site/sopkathon/product/service/MemberService.java new file mode 100644 index 0000000..ed27ab6 --- /dev/null +++ b/src/main/java/site/sopkathon/product/service/MemberService.java @@ -0,0 +1,33 @@ +package site.sopkathon.product.service; + + +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import site.sopkathon.product.common.exception.BadRequestException; +import site.sopkathon.product.domain.Member; +import site.sopkathon.product.dto.request.member.MemberSignUpRequest; +import site.sopkathon.product.dto.response.member.MemberSignUpResponse; +import site.sopkathon.product.repository.MemberRepository; + +@Service +@RequiredArgsConstructor +@Transactional(readOnly = true) +public class MemberService { + + private final MemberRepository memberRepository; + + @Transactional + public MemberSignUpResponse signUp(final MemberSignUpRequest request) { + if (!memberRepository.existsByUsername(request.username())) { + throw new BadRequestException("이미 존재하는 회원입니다."); + } + final Member savedMember = memberRepository.save( + Member.builder() + .username(request.username()) + .build() + ); + return MemberSignUpResponse.of(savedMember.getId()); + } + +}