Skip to content

Commit 8ddb9d3

Browse files
authored
Merge pull request #54 from CommitField/feat/#48
Feat: 사용자와 레포지토리 정보를 받아 시즌 별 커밋 불러오기
2 parents 069c69c + ad6f53c commit 8ddb9d3

File tree

15 files changed

+205
-9
lines changed

15 files changed

+205
-9
lines changed

.DS_Store

6 KB
Binary file not shown.

src/.DS_Store

6 KB
Binary file not shown.

src/main/.DS_Store

6 KB
Binary file not shown.

src/main/java/.DS_Store

6 KB
Binary file not shown.

src/main/java/cmf/.DS_Store

6 KB
Binary file not shown.
6 KB
Binary file not shown.
Binary file not shown.
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
package cmf.commitField.domain.commit.sinceCommit.controller;
2+
3+
import cmf.commitField.domain.commit.sinceCommit.dto.SinceCommitResponseDto;
4+
import cmf.commitField.domain.commit.sinceCommit.service.SinceCommitService;
5+
import lombok.RequiredArgsConstructor;
6+
import org.springframework.format.annotation.DateTimeFormat;
7+
import org.springframework.http.ResponseEntity;
8+
import org.springframework.web.bind.annotation.GetMapping;
9+
import org.springframework.web.bind.annotation.RequestParam;
10+
import org.springframework.web.bind.annotation.RestController;
11+
12+
import java.time.LocalDateTime;
13+
import java.time.temporal.TemporalAdjusters;
14+
import java.util.List;
15+
16+
@RestController
17+
@RequiredArgsConstructor
18+
public class SinceCommitController {
19+
private final SinceCommitService sinceCommitService;
20+
21+
@GetMapping("/api/github/commits-since")
22+
public ResponseEntity<List<SinceCommitResponseDto>> getCommits(
23+
@RequestParam String owner,
24+
@RequestParam String repo,
25+
@RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDateTime since,
26+
@RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDateTime until
27+
) {
28+
List<SinceCommitResponseDto> sinceCommits = sinceCommitService.getSinceCommits(owner, repo, since, until);
29+
30+
return ResponseEntity.ok(sinceCommits);
31+
}
32+
33+
// 시즌 별 커밋 수 불러오기
34+
35+
// 봄 시즌
36+
@GetMapping("/api/github/commits-spring")
37+
public ResponseEntity<List<SinceCommitResponseDto>> getSpringSeasonCommits(
38+
@RequestParam String owner,
39+
@RequestParam String repo
40+
) {
41+
int currentYear = LocalDateTime.now().getYear();
42+
LocalDateTime since = LocalDateTime.of(2024, 3, 1, 0, 0);
43+
LocalDateTime until = LocalDateTime.of(2024, 5, 31, 23, 59, 59);
44+
45+
List<SinceCommitResponseDto> sinceCommits = sinceCommitService.getSinceCommits(owner, repo, since, until);
46+
47+
return ResponseEntity.ok(sinceCommits);
48+
}
49+
50+
// 여름 시즌
51+
@GetMapping("/api/github/commits-summer")
52+
public ResponseEntity<List<SinceCommitResponseDto>> getSummerSeasonCommits(
53+
@RequestParam String owner,
54+
@RequestParam String repo
55+
) {
56+
int currentYear = LocalDateTime.now().getYear();
57+
LocalDateTime since = LocalDateTime.of(currentYear, 6, 1, 0, 0);
58+
LocalDateTime until = LocalDateTime.of(currentYear, 8, 31, 23, 59, 59);
59+
60+
List<SinceCommitResponseDto> sinceCommits = sinceCommitService.getSinceCommits(owner, repo, since, until);
61+
62+
return ResponseEntity.ok(sinceCommits);
63+
}
64+
65+
// 가을 시즌
66+
@GetMapping("/api/github/commits-fall")
67+
public ResponseEntity<List<SinceCommitResponseDto>> getFallSeasonCommits(
68+
@RequestParam String owner,
69+
@RequestParam String repo
70+
) {
71+
int currentYear = LocalDateTime.now().getYear();
72+
LocalDateTime since = LocalDateTime.of(currentYear, 9, 1, 0, 0);
73+
LocalDateTime until = LocalDateTime.of(currentYear, 11, 30, 23, 59, 59);
74+
75+
List<SinceCommitResponseDto> sinceCommits = sinceCommitService.getSinceCommits(owner, repo, since, until);
76+
77+
return ResponseEntity.ok(sinceCommits);
78+
}
79+
80+
// 겨울 시즌
81+
@GetMapping("/api/github/commits-winter")
82+
public ResponseEntity<List<SinceCommitResponseDto>> getWinterSeasonCommits(
83+
@RequestParam String owner,
84+
@RequestParam String repo
85+
) {
86+
int currentYear = LocalDateTime.now().getYear();
87+
LocalDateTime since = LocalDateTime.of(currentYear, 12, 1, 0, 0);
88+
LocalDateTime until = LocalDateTime.of(currentYear + 1, 2, 1, 23, 59, 59)
89+
.with(TemporalAdjusters.lastDayOfMonth()); // 윤년 고려
90+
91+
List<SinceCommitResponseDto> sinceCommits = sinceCommitService.getSinceCommits(owner, repo, since, until);
92+
93+
return ResponseEntity.ok(sinceCommits);
94+
}
95+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package cmf.commitField.domain.commit.sinceCommit.dto;
2+
3+
import lombok.Getter;
4+
import lombok.NoArgsConstructor;
5+
6+
@Getter
7+
@NoArgsConstructor
8+
public class SinceCommitResponseDto {
9+
private String sha;
10+
private Commit commit;
11+
private Author author;
12+
private String html_url;
13+
14+
15+
@Getter
16+
@NoArgsConstructor
17+
public static class Commit {
18+
private CommitAuthor author; // 원래 코드 작성자
19+
private String message;
20+
21+
@Getter
22+
@NoArgsConstructor
23+
public static class CommitAuthor {
24+
private String name; // 커밋한 사람의 깃허브 이름
25+
private String email;
26+
private String date;
27+
}
28+
}
29+
30+
@Getter
31+
@NoArgsConstructor
32+
public static class Author {
33+
private String login; // 커밋한 사람의 깃허브 id
34+
private String avatar_url;
35+
private String html_url; // 사용자의 깃허브 주소
36+
}
37+
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
package cmf.commitField.domain.commit.sinceCommit.service;
2+
3+
import cmf.commitField.domain.commit.sinceCommit.dto.SinceCommitResponseDto;
4+
import lombok.extern.slf4j.Slf4j;
5+
import org.springframework.beans.factory.annotation.Value;
6+
import org.springframework.core.ParameterizedTypeReference;
7+
import org.springframework.http.HttpHeaders;
8+
import org.springframework.http.MediaType;
9+
import org.springframework.stereotype.Service;
10+
import org.springframework.web.reactive.function.client.WebClient;
11+
12+
import java.time.LocalDateTime;
13+
import java.time.format.DateTimeFormatter;
14+
import java.util.List;
15+
16+
@Slf4j
17+
@Service
18+
public class SinceCommitService {
19+
private static final String BASE_URL = "https://api.github.com";
20+
// ?since=2024-01-01T00:00:00Z&until=2025-02-1T23:59:59Z
21+
22+
@Value("${github.token}")
23+
private String PAT;
24+
25+
private final WebClient webClient = WebClient.builder()
26+
.baseUrl(BASE_URL)
27+
.defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
28+
.build();
29+
30+
public List<SinceCommitResponseDto> getSinceCommits(String owner, String repo, LocalDateTime since, LocalDateTime until) {
31+
try {
32+
return webClient.get()
33+
.uri(uriBuilder -> uriBuilder
34+
.path("/repos/{owner}/{repo}/commits")
35+
.queryParam("since", since.format(DateTimeFormatter.ISO_DATE_TIME))
36+
.queryParam("until", until.format(DateTimeFormatter.ISO_DATE_TIME))
37+
.build(owner, repo))
38+
.header("Authorization", "bearer " + PAT)
39+
.retrieve()
40+
.bodyToMono(new ParameterizedTypeReference<List<SinceCommitResponseDto>>() {})
41+
.block();
42+
} catch (Exception e) {
43+
log.error("GitHub API 호출 중 오류 발생: {}", e.getMessage());
44+
throw new RuntimeException("GitHub API 호출 중 오류가 발생했습니다.", e);
45+
}
46+
}
47+
}
48+
/*
49+
ParameterizedTypeReference를 사용하는 주요 이유
50+
1. 제네릭 타입 정보 보존
51+
2. 복잡한 타입 구조 처리 가능
52+
3. 타입 안전성 보장
53+
4. 런타임에 올바른 타입으로 역직렬화 가능
54+
55+
ParameterizedTypeReference를 사용하지 않으면
56+
// 잘못된 예시
57+
List<GitHubCommitResponse> commits = webClient.get()
58+
.retrieve()
59+
.bodyToMono(List.class)
60+
.block();
61+
62+
// 런타임 에러 발생 가능
63+
GitHubCommitResponse commit = commits.get(0); // ClassCastException 발생 위험
64+
*/

0 commit comments

Comments
 (0)