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

feat: API 명세를 정의, 문서를 제작 (#7) #10

Merged
merged 12 commits into from
Dec 12, 2023
Merged

feat: API 명세를 정의, 문서를 제작 (#7) #10

merged 12 commits into from
Dec 12, 2023

Conversation

seokjin8678
Copy link
Contributor

관련 이슈

close #7

PR 세부 내용

News API 명세와 Spring REST Docs를 사용하여 문서화를 하였습니다.
서버 실행 후 /docs/index.html로 접속하면 API 문서 볼 수 있습니다.
그 전에 Gradle을 통해 documentation-asciidoctor Task 실행하셔야 합니다..! (혹은 build)

예외 명세는 API 문서에 나와있지 않습니다.
지금은 단순히 message 필드를 통해 어떤 예외가 발생했는지 알려주고 있습니다.
추후 회의를 통해 예외 명세를 어떻게 할 지 정의해야 할 것 같네요. (ErrorCode와 같은 값 등)

코드가 긴 관계로 세부적인 사항은 커맨트를 통해 설명 남기겠습니다.

@seokjin8678 seokjin8678 added the 뉴스 뉴스 도메인 label Dec 11, 2023
@seokjin8678 seokjin8678 requested a review from Laeng December 11, 2023 08:40
@seokjin8678 seokjin8678 self-assigned this Dec 11, 2023
@seokjin8678 seokjin8678 linked an issue Dec 11, 2023 that may be closed by this pull request
3 tasks
Copy link

github-actions bot commented Dec 11, 2023

Test Results

  5 files    5 suites   0s ⏱️
17 tests 17 ✔️ 0 💤 0
18 runs  18 ✔️ 0 💤 0

Results for commit f3f41e2.

♻️ This comment has been updated with latest results.

Comment on lines 45 to 52
@PostMapping
fun create(
@RequestBody request: NewsCreateRequest,
): ResponseEntity<ApiResponse<UUID>> {
val id = newsCommandService.create(request.toCommand())
return ResponseEntity.created("/api/v1/news/${id}".toUri())
.body(ApiResponse.success(id))
}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Service로 요청을 보낼 때 Request.toCommand() 메서드를 사용하여 의존성을 단방향으로 향하게 했습니다.

Comment on lines 21 to 26
@RestController
@RequestMapping("/api/v1/news")
class NewsControllerV1(
private val newsCommandService: NewsCommandService,
private val newsQueryService: NewsQueryService,
) {
Copy link
Contributor Author

@seokjin8678 seokjin8678 Dec 11, 2023

Choose a reason for hiding this comment

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

Service를 조회(R)를 담당하는 Query, 명령(CUD)을 담당하는 Command로 분리하여 사용했습니다.
지금은 이점이 없지만, 추후 캐싱을 적용할 때 이점이 있을것이라 판단됩니다.

Comment on lines +18 to +21
fun findAll(): List<NewsResponse> {
return newsRepository.findAll()
.map { NewsResponse.from(it) }
}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

지금은 모든 뉴스를 제공하지만, 추후 페이지네이션을 적용하여 일부만 가져올 수 있도록 해야할 것 같네요.

Comment on lines +23 to +29
fun getDetailByIdAndLanguage(id: UUID, language: Language): NewsDetailResponse {
return newsRepository.getByDetailByIdAndLanguage(id, language)
.let {
val content = it.getContentByLanguage(language)
NewsDetailResponse.of(it, content)
}
}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Repository에서 이미 id와 language에 대한 뉴스를 가져오지만, getContentByLanguage() 메서드를 사용하는 이유는 Repository에 비즈니스 로직을 담지 않게 하기 위해서 입니다.

Comment on lines 60 to 80
}.andDocument("news/find-detail") {
pathParameters(
"id" pathMeans "뉴스 식별자" constraint "UUID"
)
queryParameters(
"language" pathMeans "뉴스 언어" formattedAs ENUM(Language::class)
)
responseBody(
"data" type OBJECT means "뉴스 상세 정보",
"data.id" type STRING means "뉴스 식별자",
"data.newsType" type ENUM(NewsType::class) means "뉴스 타입",
"data.title" type STRING means "뉴스 제목",
"data.excerpt" type STRING means "뉴스 발췌",
"data.language" type ENUM(Language::class) means "뉴스 언어",
"data.publishedAt" type ZONEDDATETIME means "뉴스 발행 시간",
"data.content" type STRING means "뉴스 내용",
"data.supportLanguages" type ARRAY means "뉴스 지원 언어",
"data.originId" type NUMBER means "원본 뉴스 식별자",
"data.originUrl" type STRING means "원본 뉴스의 URL",
)
}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

코틀린의 Infix 함수를 사용한 DSL 입니다.
링크 참조하시면 될 것 같습니다.

Comment on lines +6 to +9
class KotestProjectConfig : AbstractProjectConfig() {

override fun extensions() = listOf(SpringExtension)
}
Copy link
Contributor Author

@seokjin8678 seokjin8678 Dec 11, 2023

Choose a reason for hiding this comment

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

Kotest를 Spring과 함께 사용할 때
해당 함수를 다음과 같이 재정의를 해줘야 하더군요. 😂

override fun extensions() = listOf(SpringExtension)

매 클래스 마다 함수를 재정의하기 번거로우므로, AbstractProjectConfig 클래스를 상속하여 모든 Kotest에 기본 값을 세팅해줬습니다.

- 불필요한 internal 키워드 삭제
- getAllEmptyFormats -> gatAllEmptyAttributes 메서드명 변경
- news/v1 -> v1/news
@Laeng Laeng merged commit a003a20 into dev Dec 12, 2023
3 checks passed
@seokjin8678 seokjin8678 added the 📘 문서화 문서화에 관한 작업 label Dec 12, 2023
@seokjin8678 seokjin8678 deleted the feat/#7 branch December 12, 2023 14:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
뉴스 뉴스 도메인 📘 문서화 문서화에 관한 작업
Projects
None yet
Development

Successfully merging this pull request may close these issues.

feat: API 명세를 정의하고 문서를 제작한다.
2 participants