Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[team-13 새리] API 구현 #27

Open
wants to merge 66 commits into
base: team-13
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 8 commits
Commits
Show all changes
66 commits
Select commit Hold shift + click to select a range
8adfdc9
chore: 프로젝트 초기화 설정
sallyjellyy May 3, 2021
d4c91f0
chore: 스프링 부트 초기화 및 application.properties DB 설정
sallyjellyy May 3, 2021
a920746
feat: 도메인 구현
sallyjellyy May 7, 2021
c0115da
feat: GameRepository, TeamRepository 구현
sallyjellyy May 7, 2021
c1b005b
feat: 전체 게임 리스트를 불러오는 GameService, GameController 구현
sallyjellyy May 7, 2021
aa140fb
feat: 테이블 스키마 작성
sallyjellyy May 7, 2021
4693684
test: 테스트 데이터 작성
sallyjellyy May 7, 2021
822941c
feat: 전체 게임리스트를 반환할 때 사용할 GameListDTO 구현
sallyjellyy May 7, 2021
3ab1447
feat: DTO 포맷에 맞게 테이블 결과를 불러오는 쿼리 작성
sallyjellyy May 7, 2021
cf8970d
feat: 게임 레포지토리에 있는 메서드를 이용해서 전체 게임리스트를 불러오는 기능 구현
sallyjellyy May 7, 2021
05e8a64
chore: 쿼리 디버그 설정 추가
sallyjellyy May 7, 2021
c850d7b
feat: 게임에서 팀을 아이디값으로 가지고있게 변경
sallyjellyy May 9, 2021
d7f96f7
feat: 게임, 팀, 플레이어 조회 실패시 나타낼 예외 생성
sallyjellyy May 9, 2021
e6e88ce
feat: findGameById 메서드 추가
sallyjellyy May 9, 2021
d095894
feat: 팀에서 플레이어를 Set으로 가지도록 필드 추가
sallyjellyy May 9, 2021
0372671
feat: TeamService 구현
sallyjellyy May 9, 2021
0826a95
feat: 정해둔 형식으로 한 게임의 선수정보 불러오는 메서드 구현
sallyjellyy May 9, 2021
ed9dbf4
feat: NotFoundException 구현
sallyjellyy May 9, 2021
d3d8b92
feat: ErrorCode를 enum으로 구현
sallyjellyy May 9, 2021
0c44218
feat: 리스폰스 바디로 보내줄 ErrorResponse 구현
sallyjellyy May 9, 2021
a284220
feat: GlobalExceptionHandler 구현
sallyjellyy May 9, 2021
c9905f2
style: 코드 포매팅, optimize import
sallyjellyy May 9, 2021
c9117a6
feat: 입장할 수 있는 게임인지 상태를 가져오는 browseGameStatus 구현
sallyjellyy May 9, 2021
5a12ff9
refactor: ErrorResponse 생성자 구조 변경
sallyjellyy May 9, 2021
217dec1
feat: TeamNotPlayableException 구현 및 처리
sallyjellyy May 11, 2021
6ac4369
feat: 팀 정보를 불러올 때 안의 players를 id값 순서에 맞게 정렬하도록 리스트로 변환하여 정렬
sallyjellyy May 11, 2021
2c1f637
feat: 선택한 팀의 상태에 따라 팀 정보를 반환하는 메서드 구현
sallyjellyy May 11, 2021
d2c2ccb
refactor: 팀 상태를 반환하는 메서드의 반환타입과 로직 변경
sallyjellyy May 11, 2021
49298c8
refactor: 프론트 요청에 따라 DTO 변수 순서 변경
sallyjellyy May 11, 2021
4078a93
feat: 선수 정보용 DTO 구현
sallyjellyy May 11, 2021
60b4438
refactor: atHome 에서 plateAppearance로 변수명 변경
sallyjellyy May 11, 2021
4a804f0
feat: 선수의 기록을 업데이트 할 때 받을 RequestPlayerRecordDTO 구현
sallyjellyy May 11, 2021
b6eaaf1
feat: 선수의 기록을 업데이트하는 메서드 구현
sallyjellyy May 11, 2021
42fcdb8
feat: 선수의 기록을 업데이트 해주는 메서드를 서비스단에서 구현
sallyjellyy May 11, 2021
3cb87c4
feat: 스코어 구현
sallyjellyy May 11, 2021
0d92b45
feat: 팀에서 스코어를 셋으로 가지도록 구현
sallyjellyy May 11, 2021
74e8791
feat: 스코어 테이블 추가
sallyjellyy May 11, 2021
5de440a
feat: 스코어를 추가하는 메서드 서비스단에서 구현
sallyjellyy May 11, 2021
b33453e
chore: 로그 기록용 설정 추가
sallyjellyy May 11, 2021
ce6730b
chore: 로그 기록 gitignore에 추가
sallyjellyy May 11, 2021
dee24bc
test: 테스트 데이터 추가
sallyjellyy May 11, 2021
00bdd64
feat: 게임리스트를 불러오는 곳에서 팀 아이디 추가
sallyjellyy May 11, 2021
e627055
feat: 스코어를 내보낼 때 쓸 TeamScoreDTO 구현
sallyjellyy May 11, 2021
a49744b
feat: 게임단위로 스코어를 감싸줄 GameScoreDTO 구현
sallyjellyy May 11, 2021
0a801a8
feat: 팀 스코어를 팀 아이디로 가져오는 메서드 구현
sallyjellyy May 11, 2021
d2f4f7f
feat: 스코어를 클라이언트에서 받아오고 내보내는 기능 구현
sallyjellyy May 11, 2021
3857555
feat: userSelected 필드에 추가
sallyjellyy May 11, 2021
a7e87fc
feat: userSelected 테이블에 컬럼으로 추가
sallyjellyy May 11, 2021
c3234a2
refactor: 코드 정리
sallyjellyy May 11, 2021
926d844
refactor: DTO 패키지 정리
sallyjellyy May 11, 2021
0481ce5
refactor: 의미를 명확하게 하기 위해 변수명 변경
sallyjellyy May 11, 2021
660c20d
refactor: 선수 기록 업데이트 후 팀에 저장하는 부분 수정
sallyjellyy May 11, 2021
7968604
feat: 선수 기록 업데이트하는 기능 추가
sallyjellyy May 11, 2021
aeb66b7
refactor: 평균값이 소수점 세자리까지 나올 수 있도록 AVERAGE_FORMAT 값 수정
sallyjellyy May 11, 2021
bd8aeac
refactor: patch와 post 성공 시 200대 응답코드 반환하도록 추가
sallyjellyy May 11, 2021
5d8f748
refactor: RequestPlayerRecordDTO 클래스명 변경
sallyjellyy May 11, 2021
1ac8f0a
refactor: set 초기화
sallyjellyy May 11, 2021
40ad146
refactor: 주석 추가
sallyjellyy May 11, 2021
4c41e8a
refactor: 불필요한 지역 변수 할당 제거
sallyjellyy May 14, 2021
9349f55
refactor: average 데이터 타입 변경 및 average 계산 로직 변경
sallyjellyy May 14, 2021
f6a28e0
Merge branch 'dev-BE' of https://github.com/min27604/baseball into de…
sallyjellyy May 17, 2021
a0448dc
refactor: 정렬수행의 위치 변경
sallyjellyy May 17, 2021
a1e1620
refactor: 코드 정리
sallyjellyy May 17, 2021
fb3478d
refactor: GameService에 로직을 추가
sallyjellyy May 17, 2021
dad5131
refactor: GameController, TeamController 분리
sallyjellyy May 17, 2021
d8af350
refactor: BrowseAllGames 로직 변경
sallyjellyy May 17, 2021
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
Original file line number Diff line number Diff line change
@@ -1,24 +1,29 @@
package com.codesquad.baseball.DTO;

import org.springframework.data.relational.core.mapping.Column;
import com.codesquad.baseball.domain.Team;

public class GameListDTO {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DTO인데 @Column 이 있는 것은 좀 어색한데, DTO인가요? 엔티티인가요?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

아 이 부분도 질문으로 여쭤보려했는데 깜빡했어요! DTO입니다! GameListDTO를 받아오는 레포지토리 부분을 쿼리로 짜고 컬럼명 다 맞추고 MySQL에서 쿼리가 잘 작동하는 부분까지 확인했습니다. 하지만 json으로는 모두 null로 나왔고 @Column을 붙이고 해결했지만 관련부분 검색해보아도 나오는 게 없었습니다ㅠㅡㅠ

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@min27604 댓글이 좀 늦었네요. 죄송합니다. ㅠㅠ
DTO를 받아오는 이라고 하셨는데 어디서 받아오시는 건가요? 보통의 설계로는, 레포지토리를 통해 DB row <-> Entity class 간의 정보 교환을 하고, entity <-> DTO는 다시 한 번 정보 전파 및 가공이 이뤄지는 부분인데요. 혹시 한 단계를 빼먹은 건 아니려나요?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@wheejuni 앗 네 맞아요 DB에서 가져올 때 game의 정보와 team의 정보가 조인으로 섞여있어 바로 DTO로 가져오게 했습니다.. 이렇게 하면 안 되는 거였군요ㅠㅡㅠ

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@min27604 네 맞습니다. 서로 절대 존재를 알아차리지 못하게 해주세요. (DTO - 엔티티 간)
물론 작업하다보면 변환하는 로직이 필요해서 완전히 그렇게 고립시키기는 어렵지만, 최대한 노력해 보시는게 좋아요.


@Column("gameId")
private Long gameId;

@Column("homeTeamName")
private String homeTeamName;

@Column("homeTeamId")
private Long homeTeamId;

@Column("awayTeamName")
private String awayTeamName;

@Column("awayTeamId")
private Long awayTeamId;

public static GameListDTO of(Long gameId, Team homeTeam, Team awayTeam) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 좋네요.

return new GameListDTO(
gameId,
homeTeam.getName(),
homeTeam.getId(),
awayTeam.getName(),
awayTeam.getId()
);
}

public GameListDTO(Long gameId, String homeTeamName, Long homeTeamId, String awayTeamName, Long awayTeamId) {
this.gameId = gameId;
this.homeTeamName = homeTeamName;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@

import com.codesquad.baseball.domain.Player;

import java.text.DecimalFormat;
import java.math.BigDecimal;
import java.math.RoundingMode;

public class PlayerRecordDTO {

private static final DecimalFormat AVERAGE_FORMAT = new DecimalFormat("0.000");
private static final int AVERAGE_DECIMAL_PLACES = 3;

private Long id;

private String name;
Expand All @@ -17,7 +19,7 @@ public class PlayerRecordDTO {

private int out;

private String average;
private BigDecimal average;

private int battingOrder;

Expand All @@ -26,11 +28,10 @@ public class PlayerRecordDTO {
private boolean isPitcher;

public static PlayerRecordDTO of(Player player) {
String average = "0";
if (player.getPlateAppearance() > 0) {
average = AVERAGE_FORMAT.format(player.getHit() / (float) player.getPlateAppearance());
System.out.println(average);
}
BigDecimal average = (player.getPlateAppearance() > 0) ?
BigDecimal.valueOf(player.getHit() / (double) player.getPlateAppearance()) : BigDecimal.ZERO;
average = average.setScale(AVERAGE_DECIMAL_PLACES, RoundingMode.CEILING);

return new PlayerRecordDTO(
player.getId(),
player.getName(),
Expand All @@ -44,7 +45,7 @@ public static PlayerRecordDTO of(Player player) {
);
}

private PlayerRecordDTO(Long id, String name, int plateAppearance, int hit, int out, String average,
private PlayerRecordDTO(Long id, String name, int plateAppearance, int hit, int out, BigDecimal average,
int battingOrder, int backNumber, boolean isPitcher) {
this.id = id;
this.name = name;
Expand Down Expand Up @@ -77,7 +78,7 @@ public int getOut() {
return out;
}

public String getAverage() {
public BigDecimal getAverage() {
return average;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,7 @@
import com.codesquad.baseball.domain.Score;
import com.codesquad.baseball.domain.Team;

import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

public class TeamScoreDTO {

Expand All @@ -18,15 +16,11 @@ public class TeamScoreDTO {
private List<Score> scores;

public static TeamScoreDTO of(Team team) {
List<Score> scores = team.getScores().stream()
.sorted(Comparator.comparingInt(Score::getInning))
.collect(Collectors.toList());

return new TeamScoreDTO(
team.getId(),
team.getName(),
team.isUserSelected(),
scores
team.getSortedScores()
);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,13 @@
package com.codesquad.baseball.controller;

import com.codesquad.baseball.DTO.*;
import com.codesquad.baseball.DTO.GameListDTO;
import com.codesquad.baseball.DTO.record.TeamRecordDTO;
import com.codesquad.baseball.DTO.record.request.PlayerRecordRequest;
import com.codesquad.baseball.DTO.score.GameScoreDTO;
import com.codesquad.baseball.DTO.score.TeamScoreDTO;
import com.codesquad.baseball.domain.Game;
import com.codesquad.baseball.domain.Score;
import com.codesquad.baseball.domain.Team;
import com.codesquad.baseball.service.GameService;
import com.codesquad.baseball.service.TeamService;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

Expand All @@ -20,48 +16,24 @@
public class GameController {

private final GameService gameService;
private final TeamService teamService;

public GameController(GameService gameService, TeamService teamService) {
public GameController(GameService gameService) {
this.gameService = gameService;
this.teamService = teamService;
}

@GetMapping("/games")
public List<GameListDTO> browseGames() {
return gameService.browseAllGames();
}

@GetMapping("/games/{teamId}")
public TeamDTO browseTeamStatus(@PathVariable Long teamId) {
return teamService.browseTeamStatus(teamId);
}

@GetMapping("/play/{gameId}/players")
@GetMapping("/game/{gameId}/players")
public TeamRecordDTO browseTeamPlayers(@PathVariable Long gameId) {
Game game = gameService.findGameById(gameId);
Team homeTeam = teamService.browseTeamById(game.getHomeTeamId());
Team awayTeam = teamService.browseTeamById(game.getAwayTeamId());
return new TeamRecordDTO(homeTeam, awayTeam);
return gameService.browseTeamPlayersByGameId(gameId);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

훨씬 깔끔하네요. 이게 컨트롤러가 지향해야 할 모습입니다.

}

@PostMapping("/play/{teamId}/score")
@ResponseStatus(HttpStatus.NO_CONTENT)
public void addScore(@PathVariable Long teamId, @RequestBody Score score) {
teamService.addScore(teamId, score);
}

@GetMapping("/play/{gameId}/score")
@GetMapping("/game/{gameId}/score")
public GameScoreDTO browseAllScore(@PathVariable Long gameId) {
Game game = gameService.findGameById(gameId);
TeamScoreDTO homeTeamScoreDTO = teamService.browseTeamScore(game.getHomeTeamId());
TeamScoreDTO awayTeamScoreDTO = teamService.browseTeamScore(game.getAwayTeamId());
return GameScoreDTO.of(game, homeTeamScoreDTO, awayTeamScoreDTO);
return gameService.browseGameScoreByGameId(gameId);
}

@PatchMapping("/play/{teamId}/record")
@ResponseStatus(HttpStatus.NO_CONTENT)
public void updatePlayerRecord(@PathVariable Long teamId, @RequestBody PlayerRecordRequest record) {
teamService.updatePlayerRecord(teamId, record);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package com.codesquad.baseball.controller;

import com.codesquad.baseball.DTO.TeamDTO;
import com.codesquad.baseball.DTO.record.request.PlayerRecordRequest;
import com.codesquad.baseball.domain.Score;
import com.codesquad.baseball.service.TeamService;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/baseball")
public class TeamController {

private final TeamService teamService;

public TeamController(TeamService teamService) {
this.teamService = teamService;
}

@GetMapping("/games/{teamId}")
public TeamDTO browseTeamStatus(@PathVariable Long teamId) {
return teamService.browseTeamStatus(teamId);
}

@PostMapping("/play/{teamId}/score")
@ResponseStatus(HttpStatus.NO_CONTENT)
public void addScore(@PathVariable Long teamId, @RequestBody Score score) {
teamService.addScore(teamId, score);
}

@PatchMapping("/play/{teamId}/record")
@ResponseStatus(HttpStatus.NO_CONTENT)
public void updatePlayerRecord(@PathVariable Long teamId, @RequestBody PlayerRecordRequest record) {
teamService.updatePlayerRecord(teamId, record);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,11 @@
import com.codesquad.baseball.error.exception.PlayerNotFoundException;
import org.springframework.data.annotation.Id;

import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

public class Team {

Expand Down Expand Up @@ -106,6 +109,12 @@ public void addScore(Score score) {
scores.add(score);
}

public List<Score> getSortedScores() {
return scores.stream()
.sorted(Comparator.comparingInt(Score::getInning))
.collect(Collectors.toList());
}

@Override
public String toString() {
return "Team{" +
Expand Down
Original file line number Diff line number Diff line change
@@ -1,31 +1,64 @@
package com.codesquad.baseball.service;

import com.codesquad.baseball.DTO.GameListDTO;
import com.codesquad.baseball.DTO.record.TeamRecordDTO;
import com.codesquad.baseball.DTO.score.GameScoreDTO;
import com.codesquad.baseball.DTO.score.TeamScoreDTO;
import com.codesquad.baseball.domain.Game;
import com.codesquad.baseball.domain.Team;
import com.codesquad.baseball.error.exception.GameNotFoundException;
import com.codesquad.baseball.error.exception.TeamNotFoundException;
import com.codesquad.baseball.repository.GameRepository;
import com.codesquad.baseball.repository.TeamRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

@Service
public class GameService {

private final GameRepository gameRepository;
private final TeamRepository teamRepository;

public GameService(GameRepository gameRepository) {
@Autowired
public GameService(GameRepository gameRepository, TeamRepository teamRepository) {
this.gameRepository = gameRepository;
this.teamRepository = teamRepository;
}

public Game save(Game game) {
return gameRepository.save(game);
}

public List<GameListDTO> browseAllGames() {
return gameRepository.browseAllGames();
Iterable<Game> games = gameRepository.findAll();
List<GameListDTO> gameList = new ArrayList<>();
for (Game game : games) {
Long id = game.getId();
gameList.add(GameListDTO.of(id, findHomeTeamByGameId(id), findAwayTeamByGameId(id)));
}
Comment on lines +36 to +41

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

games 할당 없이 gameRepository.findAll() 에서 출발해서 쭉 뻗어나올 수 있을 것 같은 느낌이 드는데요?
어떻게 할 수 있을까요? .map() 적절히 활용하면 가능하지 않을까요?
이러면 .collect() 해서 바로 리턴까지 한 큐에 가능할 것 같은데요. 물론 취향 문제라 새리가 판단하시는 대로 하면 되긴 해요

return gameList;
}

public Game findGameById(Long id) {
return gameRepository.findById(id).orElseThrow(GameNotFoundException::new);
}

public Team findHomeTeamByGameId(Long id) {
return teamRepository.findById(findGameById(id).getHomeTeamId()).orElseThrow(TeamNotFoundException::new);
}

public Team findAwayTeamByGameId(Long id) {
return teamRepository.findById(findGameById(id).getAwayTeamId()).orElseThrow(TeamNotFoundException::new);
}

public TeamRecordDTO browseTeamPlayersByGameId(Long id) {
return new TeamRecordDTO(findAwayTeamByGameId(id), findHomeTeamByGameId(id));
}

public GameScoreDTO browseGameScoreByGameId(Long id) {
return GameScoreDTO.of(findGameById(id), TeamScoreDTO.of(findHomeTeamByGameId(id)), TeamScoreDTO.of(findAwayTeamByGameId(id)));
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package com.codesquad.baseball.service;

import com.codesquad.baseball.DTO.record.request.PlayerRecordRequest;
import com.codesquad.baseball.DTO.TeamDTO;
import com.codesquad.baseball.DTO.record.request.PlayerRecordRequest;
import com.codesquad.baseball.DTO.score.TeamScoreDTO;
import com.codesquad.baseball.domain.Player;
import com.codesquad.baseball.domain.Score;
Expand Down