Skip to content

Commit

Permalink
Feat: 닉네임 변경 API 추가
Browse files Browse the repository at this point in the history
  • Loading branch information
wnsvy607 committed Sep 10, 2024
1 parent 19ee73b commit 86e3432
Show file tree
Hide file tree
Showing 11 changed files with 178 additions and 4 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package com.join.core.avatar.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.join.core.avatar.domain.AvatarCommand;
import com.join.core.avatar.domain.AvatarInfo;
import com.join.core.avatar.domain.AvatarService;
import com.join.core.common.response.ApiResponse;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;

@RequiredArgsConstructor
@RestController
@RequestMapping("${api.prefix}/avatars")
public class AvatarController {

private final AvatarService avatarService;

@Tag(name = "${swagger.tag.sign-up}")
@Operation(summary = "닉네임 유효성 검사 API",
description = "닉네임 유효성 검사 API")
@GetMapping("/nickname/valid")
public ApiResponse<AvatarInfo.ValidNickname> isValidNickname(AvatarCommand.ChangeNickname command) {
return ApiResponse.ok(avatarService.isValid(command));
}

}
17 changes: 17 additions & 0 deletions src/main/java/com/join/core/avatar/domain/AvatarCommand.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.join.core.avatar.domain;

import lombok.Builder;
import lombok.Getter;

public class AvatarCommand {

private AvatarCommand() {
}

@Builder
@Getter
public static class ChangeNickname {
private final String nickname;
}

}
22 changes: 22 additions & 0 deletions src/main/java/com/join/core/avatar/domain/AvatarInfo.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package com.join.core.avatar.domain;

import lombok.Builder;
import lombok.Getter;

public class AvatarInfo {

private AvatarInfo() {
}

@Builder
@Getter
public static class ValidNickname {
private final boolean isValid;
private final String message;

public static ValidNickname valid() {
return new ValidNickname(true, "사용 가능한 닉네임이에요.");
}
}

}
4 changes: 3 additions & 1 deletion src/main/java/com/join/core/avatar/domain/AvatarReader.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package com.join.core.avatar.domain;

public interface AvatarReader {
Avatar getAvatarByToken(String avatarToken);
Avatar getAvatarByToken(String avatarToken);

boolean existsByNickname(String nickname);

}
7 changes: 7 additions & 0 deletions src/main/java/com/join/core/avatar/domain/AvatarService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.join.core.avatar.domain;

public interface AvatarService {

AvatarInfo.ValidNickname isValid(AvatarCommand.ChangeNickname command);

}
29 changes: 29 additions & 0 deletions src/main/java/com/join/core/avatar/domain/AvatarServiceImpl.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package com.join.core.avatar.domain;

import java.util.List;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import lombok.RequiredArgsConstructor;

@RequiredArgsConstructor
@Transactional(readOnly = true)
@Service
public class AvatarServiceImpl implements AvatarService {

private final List<NicknameValidator> nicknameValidatorList;

@Override
public AvatarInfo.ValidNickname isValid(AvatarCommand.ChangeNickname command) {

for (NicknameValidator validator : nicknameValidatorList) {
AvatarInfo.ValidNickname validationResult = validator.validate(command);
if (!validationResult.isValid())
return validationResult;
}

return AvatarInfo.ValidNickname.valid();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.join.core.avatar.domain;

import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import lombok.RequiredArgsConstructor;

@RequiredArgsConstructor
@Order(2)
@Component
public class NicknameDuplicationValidator implements NicknameValidator {

private final AvatarReader avatarReader;

@Override
public AvatarInfo.ValidNickname validate(AvatarCommand.ChangeNickname command) {
if (avatarReader.existsByNickname(command.getNickname()))
return new AvatarInfo.ValidNickname(false, "이미 사용 중인 닉네임이에요.");

return AvatarInfo.ValidNickname.valid();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.join.core.avatar.domain;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

@Order(1)
@Component
public class NicknameFormatValidator implements NicknameValidator {

private static final Pattern pattern = Pattern.compile("^[가-힣a-zA-Z0-9]{2,7}$");

@Override
public AvatarInfo.ValidNickname validate(AvatarCommand.ChangeNickname command) {
Matcher matcher = pattern.matcher(command.getNickname());
if (!matcher.matches())
return new AvatarInfo.ValidNickname(false, "2-7자리 한글/영문/숫자로 입력해주세요.");

return AvatarInfo.ValidNickname.valid();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.join.core.avatar.domain;

public interface NicknameValidator {

AvatarInfo.ValidNickname validate(AvatarCommand.ChangeNickname command);

}
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,10 @@ public Avatar getAvatarByToken(String avatarToken) {
.orElseThrow(() -> new EntityNotFoundException(ErrorCode.AVATAR_NOT_FOUND));
}

@Transactional(readOnly = true)
@Override
public boolean existsByNickname(String nickname) {
return avatarRepository.existsByNickname(nickname);
}

}
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
package com.join.core.avatar.repository;

import com.join.core.avatar.domain.Avatar;
import java.util.Optional;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;

import java.util.Optional;
import com.join.core.avatar.domain.Avatar;

public interface AvatarRepository extends JpaRepository<Avatar, Long> {
Optional<Avatar> findByAvatarToken(String avatarToken);
Optional<Avatar> findByAvatarToken(String avatarToken);

@Query("select (count(a) > 0) from Avatar a where a.nickname = :nickname")
boolean existsByNickname(@Param("nickname") String nickname);

}

0 comments on commit 86e3432

Please sign in to comment.