๋ณธ๋ฌธ์œผ๋กœ ๋ฐ”๋กœ๊ฐ€๊ธฐ
๋ฐ˜์‘ํ˜•

 

์ด๋Ÿฐ ์ปค๋ฐ‹ ํžˆ์Šคํ† ๋ฆฌ๋ฅผ ๊ฐ€์ ธ์™€์„œ ํฌํŠธํด๋ฆฌ์˜ค ์‚ฌ์ดํŠธ์— ๋ฟŒ๋ ค์ฃผ๊ณ  ์‹ถ์—ˆ๋‹ค.

 

์™„์„ฑ ํ™”๋ฉด

 

ํ•ด๋‹น ๊ธฐ๋Šฅ์€ GitHub API๋กœ ํžˆ์Šคํ† ๋ฆฌ๋ฅผ ๋ถˆ๋Ÿฌ์˜ฌ ์ˆ˜ ์žˆ๋‹ค.

ํ•„์š”ํ•œ ๊ธฐ๋Šฅ : GitHub API ์—”๋“œํฌ์ธํŠธ, Access Token ๋ฐœ๊ธ‰


1. GitHub API ์†Œ๊ฐœ

  • GitHub์€ REST API๋ฅผ ์ œ๊ณตํ•˜๊ณ , repos ์—”๋“œํฌ์ธํŠธ๋ฅผ ์ด์šฉํ•˜๋ฉด ์ปค๋ฐ‹ ํžˆ์Šคํ† ๋ฆฌ๋ฅผ ์กฐํšŒํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ๊ธฐ๋ณธ ์ฃผ์†Œ:
https://api.github.com/repos/{owner}/{repo}/commits

2. Personal Access Token ๋ฐœ๊ธ‰

  1. GitHub ๋กœ๊ทธ์ธ → Settings → Developer settings → Personal access tokens
  2. Fine-grained token ๋˜๋Š” Classic token ๋ฐœ๊ธ‰
  3. ์ตœ์†Œ ๊ถŒํ•œ์€ repo → contents:read ์ •๋„๋ฉด ์ถฉ๋ถ„

์ฃผ์˜: ํ† ํฐ์€ ์ ˆ๋Œ€ ๊ณต๊ฐœ ์ €์žฅ์†Œ์— ์˜ฌ๋ฆฌ๋ฉด ์•ˆ๋จ.

 

๊ฐ€์žฅ ๊ฐ„๋‹จํ•œ ๋ฐฉ๋ฒ•์€ javascript๋กœ API๋ฅผ ์š”์ฒญํ•˜๋ฉด ๋˜์ง€๋งŒ,

์šฐ๋ฆฌ๋Š” ํ† ํฐ์ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์„œ๋น„์Šค๋ฅผ ๋งŒ๋“ค์–ด์„œ ๊ฐ€์ ธ์˜ค๋ ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค.

RestTemplate์ด๋‚˜ WebClient๋กœ ๊ตฌํ˜„ ๊ฐ€๋Šฅํ•˜์ง€๋งŒ, ์—ฌ๊ธฐ์„œ๋Š” ๊ฐ„๋‹จํ•˜๊ฒŒ RestTemplate์œผ๋กœ ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.


1.Service ํด๋ž˜์Šค

@Service
public class GitHubService {

    private final RestTemplate restTemplate = new RestTemplate();
    private static final String GITHUB_API_URL = "https://api.github.com/repos/{owner}/{repo}/commits";

    public String getCommits(String owner, String repo, String token) {
        HttpHeaders headers = new HttpHeaders();
        headers.set("Authorization", "token " + token);
        headers.set("Accept", "application/vnd.github+json");

        HttpEntity<String> entity = new HttpEntity<>(headers);

        ResponseEntity<String> response = restTemplate.exchange(
                GITHUB_API_URL,
                HttpMethod.GET,
                entity,
                String.class,
                owner,
                repo
        );

        return response.getBody();
    }
}

2.Controller ํด๋ž˜์Šค

@RestController
@RequestMapping("/github")
public class GitHubController {

    private final GitHubService gitHubService;

    public GitHubController(GitHubService gitHubService) {
        this.gitHubService = gitHubService;
    }

    @GetMapping("/commits/{owner}/{repo}")
    public String getCommits(
            @PathVariable String owner,
            @PathVariable String repo,
            @RequestHeader("Authorization") String token
    ) {
        // token์€ "Bearer xxx" ๋ง๊ณ  "token xxx" ํ˜•์‹์œผ๋กœ ๋ณด๋‚ด์•ผ ํ•จ
        return gitHubService.getCommits(owner, repo, token.replace("token ", ""));
    }
}

3.์‚ฌ์šฉ ๋ฐฉ๋ฒ•

1. ์„œ๋ฒ„ ์‹คํ–‰

2. API ํ˜ธ์ถœ (Postman์ด๋‚˜ ๋ธŒ๋ผ์šฐ์ €์—์„œ)

curl -H "Authorization: token {YOUR_GITHUB_TOKEN}" \
http://localhost:8080/github/commits/{owner}/{repo}

3.๊ฒฐ๊ณผ: GitHub์—์„œ ๋‚ด๋ ค์ฃผ๋Š” JSON์ด ๊ทธ๋Œ€๋กœ ์ถœ๋ ฅ๋จ

[
  {
    "sha": "a1b2c3...",
    "commit": {
      "author": {
        "name": "ํ™๊ธธ๋™",
        "email": "hong@test.com",
        "date": "2025-08-27T05:21:20Z"
      },
      "message": "Fix bug in login"
    },
    "html_url": "https://github.com/owner/repo/commit/a1b2c3"
  }
]

๐Ÿ‘‰ ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ์›น ์‚ฌ์ดํŠธ์— Spring Boot ๊ธฐ๋ฐ˜ GitHub API ์—ฐ๋™์ด ๊ฐ€๋Šฅํ•˜๋‹ค.

 

๋˜ํ•œ ์ด ๋ฐ์ดํ„ฐ๋ฅผ ํ”„๋ก ํŠธ์—”๋“œ(React, Vue ๋“ฑ)์—์„œ ๋ฐ›์•„์™€์„œ ํƒ€์ž„๋ผ์ธ ํ˜•ํƒœ๋กœ ํ‘œํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค.

ํŠน์ • ๋ธŒ๋žœ์น˜๋งŒ ์กฐํšŒํ•˜๊ฑฐ๋‚˜ (?sha=๋ธŒ๋žœ์น˜๋ช…), ํŠน์ • ํŒŒ์ผ์— ๋Œ€ํ•œ ์ปค๋ฐ‹ ๊ธฐ๋ก๋งŒ ๋ถˆ๋Ÿฌ์˜ฌ ์ˆ˜๋„ ์žˆ๋‹ค(?path=ํŒŒ์ผ๋ช…)

ํฌํŠธํด๋ฆฌ์˜ค ์‚ฌ์ดํŠธ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ, ํŒ€ํ”„๋กœ์ ํŠธ ๊ธฐ๋ก ๊ด€๋ฆฌ, ์ตœ๊ทผ ์ž‘์—… ํ˜„ํ™ฉ ํŽ˜์ด์ง€ ๊ฐ™์€๊ณณ์—๋„ ์‘์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

 

๋ฐ˜์‘ํ˜•