본문 바로가기
프로젝트/PongGame

RelationController

by 히포파타마스 2022. 6. 3.

RelationController

사전에 정의한 API 명세에 따른 Controller를 구현한다.

 

 

 

 

1. RelationValidator

Controller로 들어오는 accountId 간에 검증을 처리한다.

Controller로 들어오는 accountId는 별개의 파라미터로 Spring에서 제공하는 Validator 기능을 사용할 수 없기에 따로 RelationValidator 클래스를 생성하고 Controller에서 해당 Validator를 적용한다.

 

 

 

■ RelationValidator

Account간 Relation의 상태에 대해 검증을 시행한다.

 

[RelationValidator]

@Component
@RequiredArgsConstructor
public class RelationValidator {

    private final RelationRepository relationRepository;
    private final AccountRepository accountRepository;

    private void isBlockRelationByAccount(Account fromAccount, Account toAccount) {
        if (relationRepository.existsByFromAccountAndToAccountAndRelationStateEquals(fromAccount, toAccount,
                RelationState.BLOCK)) {
            throw new IllegalRequestException("차단된 회원입니다.");
        }
    }

    public void isBlockRelation(Long fromAccountId, Long toAccountId) {
        Account fromAccount = accountRepository.findById(fromAccountId)
                .orElseThrow(() -> new NonExistResourceException("해당 Id를 갖는 Account를 찾을 수 없습니다."));
        Account toAccount = accountRepository.findById(toAccountId)
                .orElseThrow(() -> new NonExistResourceException("해당 Id를 갖는 Account를 찾을 수 없습니다."));

        isBlockRelationByAccount(fromAccount, toAccount);
    }

    public void validRequestFriend(Long fromAccountId, Long toAccountId) {
        Account fromAccount = accountRepository.findById(fromAccountId)
                .orElseThrow(() -> new NonExistResourceException("해당 Id를 갖는 Account를 찾을 수 없습니다."));
        Account toAccount = accountRepository.findById(toAccountId)
                .orElseThrow(() -> new NonExistResourceException("해당 Id를 갖는 Account를 찾을 수 없습니다."));

        isBlockRelationByAccount(fromAccount, toAccount);
        if (relationRepository.existsByFromAccountAndToAccountAndRelationStateEquals(fromAccount, toAccount
                , RelationState.FRIEND)) {
            throw new IllegalRequestException("이미 친구 관계입니다.");
        }
        if (fromAccount.equals(toAccount)) {
            throw new IllegalRequestException("자기자신에 대한 요청입니다.");
        }
        if (relationRepository.existsByFromAccountAndToAccountAndRelationStateEquals(fromAccount, toAccount,
                RelationState.REQUEST)) {
            throw new DuplicationRequestException("이미 존재하는 요청입니다.");
        }
    }
}

 

 

□ isBlockRelationByAccount

fromAccount -> toAccount 방향의 "차단" 상태인 Relation이 있으면 에러를 발생시킨다.

파라미터로 Id가 아닌 Account를 받는다.

 

[isBlockRelationByAccount]

public void isBlockRelationByAccount(Account fromAccount, Account toAccount) {
    if (relationRepository.existsByFromAccountAndToAccountAndRelationStateEquals(fromAccount, toAccount,
            RelationState.BLOCK)) {
        throw new IllegalRequestException("차단된 회원입니다.");
    }
}

 

 

□ isBlockRelation

fromAccount -> toAccount 방향의 "차단" 상태인 Relation이 있으면 에러를 발생시킨다.

 

[isBlockRelation]

public void isBlockRelation(Long fromAccountId, Long toAccountId) {
    Account fromAccount = accountRepository.findById(fromAccountId)
            .orElseThrow(() -> new NonExistResourceException("해당 Id를 갖는 Account를 찾을 수 없습니다."));
    Account toAccount = accountRepository.findById(toAccountId)
            .orElseThrow(() -> new NonExistResourceException("해당 Id를 갖는 Account를 찾을 수 없습니다."));

    isBlockRelationByAccount(fromAccount, toAccount);
}

 

 

□ validRequestFriend

"친구 요청"을 처리하는 API에서 매개변수로 받아지는 AccountId에 대해 검증을 처리하는 메서드

 

[validRequestFriend]

public void validRequestFriend(Long fromAccountId, Long toAccountId) {
    Account fromAccount = accountRepository.findById(fromAccountId)
            .orElseThrow(() -> new NonExistResourceException("해당 Id를 갖는 Account를 찾을 수 없습니다."));
    Account toAccount = accountRepository.findById(toAccountId)
            .orElseThrow(() -> new NonExistResourceException("해당 Id를 갖는 Account를 찾을 수 없습니다."));

    isBlockRelationByAccount(fromAccount, toAccount);
    if (relationRepository.existsByFromAccountAndToAccountAndRelationStateEquals(fromAccount, toAccount
            , RelationState.FRIEND)) {   //[1]
        throw new IllegalRequestException("이미 친구 관계입니다.");
    }
    if (fromAccount.equals(toAccount)) {   //[2]
        throw new IllegalRequestException("자기자신에 대한 요청입니다.");
    }
    if (relationRepository.existsByFromAccountAndToAccountAndRelationStateEquals(fromAccount, toAccount,
            RelationState.REQUEST)) {   //[3]
        throw new DuplicationRequestException("이미 존재하는 요청입니다.");
    }
}

● [1] : 이미 "친구" 상태인 Relation이 있을 경우 에러 발생

● [2] : "친구 요청"을 자기 자신에게 시행할 경우 에러 발생

● [3] : 이미 "친구 요청" 상태인 Relation이 있을 경우 에러 발생

 

 

 

 

2. RelationController

■ RelationController

[RelationController]

@RestController
@RequiredArgsConstructor
public class RelationController {

    private final RelationService relationService;
    private final RelationValidator relationValidator;
    
    .
    .
    .
    
}

 

 

 

■ 생성, 변경, 삭제

Relation을 생성하거나 삭제하고, RelationState를 변경하는 API

 

[생성, 변경]

@PostMapping("/relation/request/{accountId}")
public ResultMessage requestFriend(@LoginAccountId Long loginAccountId, @PathVariable Long accountId) {
    relationValidator.validRequestFriend(loginAccountId, accountId);
    relationService.requestFriend(loginAccountId, accountId);
    return new ResultMessage("success friend request");
}

@PostMapping("/relation/request/accept/{accountId}")
public ResultMessage acceptFriend(@LoginAccountId Long loginAccountId, @PathVariable Long accountId) {
    relationValidator.isBlockRelation(loginAccountId, accountId);
    relationService.acceptFriend(accountId, loginAccountId);
    return new ResultMessage("success accept friend request");
}

@PostMapping("/relation/request/reject/{accountId}")
public ResultMessage rejectFriend(@LoginAccountId Long loginAccountId, @PathVariable Long accountId) {
    relationService.rejectRequest(accountId, loginAccountId);
    return new ResultMessage("success reject friend request");
}

@PostMapping("/relation/block/{accountId}")
public ResultMessage block(@LoginAccountId Long loginAccountId, @PathVariable Long accountId) {
    relationValidator.isBlockRelation(loginAccountId, accountId);
    relationService.block(loginAccountId, accountId);
    return new ResultMessage("success block Account");
}

@PostMapping("/relation/unBlock/{accountId}")
public ResultMessage unBlock(@LoginAccountId Long loginAccountId, @PathVariable Long accountId) {
    relationService.unBlock(loginAccountId, accountId);
    return new ResultMessage("success unBlock Account");
}

파라미터로 받아진 acoountId의 Account 간에 검증을 RelationValidator를 통해 처리한 후, RelationService에서 Business Logic을 적용한다.

 

 

 

■ 조회

Relation에 연관된 Acoount를 조회하는 API

 

[조회]

@GetMapping("relation/request/all")
public Result<List<AccountDto>> findAllRequest(@LoginAccountId Long loginAccountId) {
    List<AccountDto> accountDtoList = relationService.findAllRequest(loginAccountId).stream()
            .map(relation -> new AccountDto(relation.getToAccount()))
            .collect(Collectors.toList());
    return new Result<>(accountDtoList);
}

@GetMapping("/relation/requests")
public Page<AccountDto> findRequestsByPage(@LoginAccountId Long loginAccountId, Pageable pageable) {
    QueryResults<Relation> queryResults = relationService.findRequestsByPage(loginAccountId, pageable);
    List<AccountDto> accountDtoList = queryResults.getResults().stream()
            .map(relation -> new AccountDto(relation.getToAccount()))
            .collect(Collectors.toList());
    return new PageImpl<>(accountDtoList, pageable, queryResults.getTotal());
}

@GetMapping("/relation/requestFromOther/all")
public Result<List<AccountDto>> findAllRequestFromOther(@LoginAccountId Long loginAccountId) {
    List<AccountDto> accountDtoList = relationService.findAllRequestFromOther(loginAccountId).stream()
            .map(relation -> new AccountDto(relation.getFromAccount()))
            .collect(Collectors.toList());
    return new Result<>(accountDtoList);
}


@GetMapping("/relation/requestsFromOther")
public Page<AccountDto> findRequestsFromOtherByPage(@LoginAccountId Long loginAccountId, Pageable pageable) {
    QueryResults<Relation> queryResults = relationService.findRequestsFromOtherByPage(loginAccountId, pageable);
    List<AccountDto> accountDtoList = queryResults.getResults().stream()
            .map(relation -> new AccountDto(relation.getFromAccount()))
            .collect(Collectors.toList());
    return new PageImpl<>(accountDtoList, pageable, queryResults.getTotal());
}

@GetMapping("/relation/friend/all")
public Result<List<AccountDto>> findAllFriend(@LoginAccountId Long loginAccountId, Pageable pageable) {
    List<AccountDto> accountDtoList = relationService.findAllFriend(loginAccountId).stream()
            .map(relation -> new AccountDto(relation.getToAccount()))
            .collect(Collectors.toList());
    return new Result<>(accountDtoList);
}

@GetMapping("/relation/friends")
public Page<AccountDto> findFriends(@LoginAccountId Long loginAccountId, Pageable pageable) {
    QueryResults<Relation> queryResults = relationService.findFriendsByPage(loginAccountId, pageable);
    List<AccountDto> accountDtoList = queryResults.getResults().stream()
            .map(relation -> new AccountDto(relation.getToAccount()))
            .collect(Collectors.toList());
    return new PageImpl<>(accountDtoList, pageable, queryResults.getTotal());
}

@GetMapping("/relation/block/all")
public Result<List<AccountDto>> findAllBlock(@LoginAccountId Long loginAccountId) {
    List<AccountDto> accountDtoList = relationService.findAllBlock(loginAccountId).stream()
            .map(relation -> new AccountDto(relation.getToAccount()))
            .collect(Collectors.toList());
    return new Result<>(accountDtoList);
}

@GetMapping("/relation/blocks")
public Page<AccountDto> findBlockAccounts(@LoginAccountId Long loginAccountId, Pageable pageable) {
    QueryResults<Relation> queryResults = relationService.findBlocksByPage(loginAccountId, pageable);
    List<AccountDto> accountDtoList = queryResults.getResults().stream()
            .map(relation -> new AccountDto(relation.getToAccount()))
            .collect(Collectors.toList());
    return new PageImpl<>(accountDtoList, pageable, queryResults.getTotal());
}

RelationService에서 Relation을 찾은 후, fromAccoun와 toAccount 중 반환할 Account를 찾아 List나 Page로 반환한다.

Account는 모두 AccountDto로 옮겨져서 반환된다.

 

 

 

'프로젝트 > PongGame' 카테고리의 다른 글

RelationService  (0) 2022.06.03
RelationRepository  (0) 2022.06.01
Relation API 명세  (0) 2022.05.30
myLogin  (0) 2022.05.18
Account Controller  (0) 2022.05.11

댓글