-
Notifications
You must be signed in to change notification settings - Fork 0
[Feat/#3] Github API 데이터 처리를 위한 프로토타입 Demo 서버 구현 #4
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
base: main
Are you sure you want to change the base?
Changes from all commits
8bdca4f
3f5f3ba
61ee5ff
d36072f
5e20d98
af8b55e
9492ede
5f030bf
50feb77
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| package com.softgallery.profilegameserverdemo.controller; | ||
|
|
||
| import com.softgallery.profilegameserverdemo.service.GithubAPIService; | ||
| import org.springframework.web.bind.annotation.GetMapping; | ||
| import org.springframework.web.bind.annotation.PathVariable; | ||
| import org.springframework.web.bind.annotation.RestController; | ||
|
|
||
| @RestController | ||
| public class GithubAPIController { | ||
| private final GithubAPIService githubAPIService = new GithubAPIService(); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 여기서 final 키워드를 쓴 이유가 뭔지 알려주실 수 있나요? 또한, GithubAPIService는 어떤 객체인지 궁금합니다!
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이름에서 알 수 있듯이 Github API를 활용할 수 있게 만들어주는 서비스를 담당하는 객체 필드를 의미합니다. 실제로 API에서 데이터를 불러오는 로직은 Controller가 아닌 Service에서 처리합니다. 해당 객체는 이후에 다른 객체로 변환될 일 없이 쭉 불변이므로 final access modifier를 사용했습니다.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 아하 이해했습니다! 객체 필드에 대한 로직은 모두 Service에서 처리하기 때문이군요! 좋은 설명 감사합니다! |
||
|
|
||
| @GetMapping("/commit/{name}") | ||
| public String getCommitInfoByName(@PathVariable("name") String name) { | ||
| System.out.println(name); | ||
| String repo = "spring-roomescape-playground"; // repo 이름을 수정하여 넣을 것 | ||
|
|
||
| return githubAPIService.getCommits(name, repo); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| package com.softgallery.profilegameserverdemo.controller; | ||
|
|
||
| import com.softgallery.profilegameserverdemo.domain.Profile; | ||
| import com.softgallery.profilegameserverdemo.service.ProfileService; | ||
| import org.springframework.stereotype.Controller; | ||
| import org.springframework.web.bind.annotation.GetMapping; | ||
| import org.springframework.web.bind.annotation.PathVariable; | ||
| import org.springframework.web.bind.annotation.ResponseBody; | ||
| import org.springframework.web.bind.annotation.RestController; | ||
|
|
||
| @Controller | ||
| public class MainController { | ||
| private final ProfileService profileService = new ProfileService(); | ||
|
|
||
| @GetMapping("/") | ||
| public String test() { return "test"; } | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. String이라는 타입의 변수명을 test()로 지정할 수 있나요? 저 이 코드가 잘 이해가 안갑니다. String인데 함수형으로 오른쪽에 test() { return "test"; }이런식으로 선언되어있어요. public String test = "test";랑 뭐가 다른거죠 😢
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 그리고 이 코드는 왜 있는건가요?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. (저도 저 코드 이해하는데 참~ 오래 걸렸는데요~~)
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이야 그러한 기능이라면, 서비스 단계에서는 test라는 명칭 말고, 다른 명칭으로 많이 구현이 될 것 같은데 제 추측이 맞을까요?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 실제 서비스를 해보지 않아서 잘은 모르겠지만, 가장 기본이자 메인이 되는 페이지이기 때문에 home, main, 서비스 이름 등으로 명칭을 정하는 것으로 알고 있습니다. |
||
|
|
||
| @GetMapping("/{name}") | ||
| @ResponseBody | ||
| public Profile searchProfile(@PathVariable("name") String name) { | ||
| System.out.println(name); | ||
|
|
||
| return profileService.getProfile(name); | ||
| } | ||
|
|
||
| @GetMapping("/profile") | ||
| @ResponseBody | ||
| public Profile printProfile() { | ||
| return new Profile(0L, "Jaehoon", "00:01:02", "2024-01-01"); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,34 @@ | ||
| package com.softgallery.profilegameserverdemo.domain; | ||
|
|
||
| import java.time.LocalDate; | ||
| import java.time.LocalTime; | ||
|
|
||
| public class Profile { | ||
| private final Long id; | ||
| private final String name; | ||
| private final LocalTime recentTime; | ||
| private final LocalDate recentDate; | ||
|
|
||
| public Profile(final Long id, final String name, final String time, final String date) { | ||
| this.id = id; | ||
| this.name = name; | ||
| this.recentTime = LocalTime.parse(time); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. LocalTime.parse(time)을 하면, recentTime은 어떻게 초기화 되나요?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. HH:mm:ss 형식으로 들어온 String 데이터를 시간 처리 객체인 LocalTime 객체로 변환합니다. |
||
| this.recentDate = LocalDate.parse(date); | ||
| } | ||
|
|
||
| public Long getId() { | ||
| return id; | ||
| } | ||
|
|
||
| public String getName() { | ||
| return name; | ||
| } | ||
|
|
||
| public LocalTime getRecentTime() { | ||
| return recentTime; | ||
| } | ||
|
|
||
| public LocalDate getRecentDate() { | ||
| return recentDate; | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| package com.softgallery.profilegameserverdemo.service; | ||
|
|
||
| import org.springframework.stereotype.Service; | ||
| import org.springframework.web.client.RestTemplate; | ||
|
|
||
| @Service | ||
| public class GithubAPIService { | ||
| private final String GITHUB_API_URL = "https://api.github.com"; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 기본 baseURL이 되는 코드인가보네요!
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 맞습니다! |
||
|
|
||
| private final RestTemplate restTemplate = new RestTemplate(); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. RestTemplate()는 어떤 객체인지 설명해주실 수 있나요?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. REST API에서 보내주는 값을 저장하기 위해 사용해야되는 템플릿입니다. 하단의 코드를 보시면 restTemplate.queryForObject() 메서드로 데이터를 Object 형태로 받아오는 것을 알 수 있습니다. |
||
|
|
||
| public GithubAPIService() { } | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이후에는 어떤 기능이 해당 함수에 추가될 가능성이 있나요?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 클래스 생성자라 특정한 기능을 하는 함수가 추가되지는 않겠지만, 스프링이 RestTemplate 필드에 의존성을 추가하는 코드가 들어갈 예정입니다. |
||
|
|
||
| public String getCommits(String owner, String repo) { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. commit을 가져오는 함수인걸까요? 뭔가 getUrlString이런 함수명은 url의 string값을 가져온다... 이런식으로 이해가 되는데 커밋을 가져온다는건 뭔지 모르겠어서 어떤 기능을 하는지 잘 이해가 가지 않습니다! 설명해주실 수 있나요?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. (함수명은 GPT가 짰어요...)
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 감사합니다~ |
||
| String url = GITHUB_API_URL + "/repos/" + owner + "/" + repo + "/commits"; | ||
| return restTemplate.getForObject(url, String.class); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,34 @@ | ||
| package com.softgallery.profilegameserverdemo.service; | ||
|
|
||
| import com.softgallery.profilegameserverdemo.domain.Profile; | ||
| import java.util.ArrayList; | ||
|
|
||
| public class ProfileService { | ||
| private final ArrayList<Profile> profiles = new ArrayList<>(); | ||
|
|
||
| public ProfileService() { | ||
| initialize(); | ||
| } | ||
|
|
||
| // Initialization with test-cases | ||
| private void initialize() { | ||
| profiles.add(new Profile(1L, "Jaehoon", "00:01:02", "2024-01-01")); | ||
| profiles.add(new Profile(2L, "SHKim55", "23:00:00", "2024-12-23")); | ||
| profiles.add(new Profile(3L, "Sumin", "22:00:00", "2023-12-23")); | ||
| profiles.add(new Profile(4L, "YongWoo", "21:00:00", "2023-11-23")); | ||
| profiles.add(new Profile(5L, "Hangyul", "20:00:00", "2023-10-23")); | ||
| } | ||
|
|
||
| public ArrayList<Profile> getAllProfiles() { | ||
| return profiles; | ||
| } | ||
|
|
||
| // Find profile by name | ||
| public Profile getProfile(String name) { | ||
| for(Profile profile : profiles) { | ||
| if (profile.getName().equals(name)) | ||
| return profile; | ||
| } | ||
| return new Profile(0L, "No Such User", "00:00:00", "0000-00-00"); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| <!DOCTYPE html> | ||
| <html xmlns:th="http://www.thymeleaf.org"> | ||
| <head> | ||
| <meta charset="UTF-8"> | ||
| <title>Test Page</title> | ||
| </head> | ||
| <body> | ||
| Testing | ||
| </body> | ||
| </html> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@RestController는 어떤 역할을 하는 코드인가요?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Spring에게 해당 클래스가 Rest API를 처리하는 Controller의 역할을 한다고 알려주는 Annotation 입니다. 이걸 붙이면 자동으로 Spring Bean으로 등록됩니다.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Spring Bean이 뭔가요? 재사용 가능한 소프트웨어 컴포넌트라고 나오는데, 해당 컨트롤러가 Spring Bean으로 등록이되면 어떤 이점이 있나요?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bean은 스프링에서 직접 관리해주는 객체라고 보시면 됩니다. 자동 의존관계 주입(Dependency Injection, DI)이라는 스프링의 핵심 기능을 사용하기 위해 등록하여야 하며, 등록이 되게 되면 한 종류의 객체는 전체 프로그램 내에서 하나만 생성되어 (Singleton) 재사용이 가능합니다. 여기서는 GithubAPIController 자체가 하나의 Bean이므로 프로그램 내에 다른 클래스에서 새로운 GithubAPIController 필드를 선언해도 처음에 생성된 것과 똑같은 Controller 객체가 필드에 주입되게 됩니다.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
자동 의존관계 주입이 뭔지 혹시 설명해주실 수 있을까요? 해당 용어를 제외하고는, 어떤 역할을 하는지 이해는 갑니다!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
제대로 설명하기엔 어려운 개념이라 간단하게만 설명하자면, A클래스에서 B 타입의 필드를 생성할 때 선언을 한 뒤 new 키워드를 이용하여 B 객체를 할당을 받게 되면 A는 B에 의존한다고 표현합니다. A클래스는 B 객체 필드 없이는 동작하지 못하기 때문입니다. 여기서 자동으로 의존관계를 주입한다는 것은 객체의 생성자를 이용하여 스프링이 객체 내 필드를 자동으로 생성시켜준다는 것을 의미합니다. Int a = new Int()와 같은 형식으로 직접 할당해 줄 필요가 없습니다.