Skip to content

Conversation

@zyovn
Copy link
Member

@zyovn zyovn commented Jul 20, 2025

✔️ 연관 이슈

📝 작업 내용

T MAP 보행자 API를 연동하여 도보 최적 경로 길찾기 제공

📸 스크린샷 (선택)

스크린샷 2025-07-20 044030

Summary by CodeRabbit

  • 신규 기능

    • 도보 길찾기 API 엔드포인트가 추가되어 출발지와 도착지 정보를 입력하면 최적의 도보 경로, 총 거리, 소요 시간, 경로 단계별 상세 정보를 제공합니다.
    • 외부 T MAP API와 연동하여 실시간 도보 경로 데이터를 받아옵니다.
    • T MAP 기반 도보 경로 요청 및 응답 처리를 위한 설정과 클라이언트, 매퍼, 서비스가 도입되었습니다.
  • 문서화

    • 도보 길찾기 API에 대한 Swagger 문서가 추가되어 API 사용법과 응답 예시를 확인할 수 있습니다.

@zyovn zyovn self-assigned this Jul 20, 2025
@zyovn zyovn added the 💡 feature 기능 구현 및 개발 label Jul 20, 2025
@coderabbitai
Copy link

coderabbitai bot commented Jul 20, 2025

Walkthrough

이 변경사항은 TMap API와 연동하여 도보 최적 경로를 제공하는 새로운 워킹(도보) 경로 API 전체 레이어(컨트롤러, 서비스, 클라이언트, 매퍼, DTO, 설정 등)를 프로젝트에 추가합니다. 또한 WebFlux 의존성 및 외부 설정 바인딩을 위한 구성을 포함합니다.

Changes

파일/경로 요약 변경 요약
build.gradle spring-boot-starter-webflux 의존성 추가
src/main/java/com/wayble/server/ServerApplication.java @EnableConfigurationProperties(TMapProperties.class) 애노테이션 추가
.../common/config/WebClientConfig.java WebClient 및 TMap 전용 WebClient 빈 설정 클래스 추가
.../direction/controller/WalkingController.java
.../controller/swagger/WalkingSwagger.java
워킹 경로 API 컨트롤러 및 Swagger 인터페이스 추가
.../direction/external/tmap/TMapClient.java
.../TMapProperties.java
TMap API 클라이언트 및 외부 설정 바인딩용 레코드 클래스 추가
.../external/tmap/dto/request/TMapRequest.java 도보 경로 요청 DTO(레코드) 추가, 빌더 패턴 적용
.../external/tmap/dto/response/TMapParsingResponse.java
.../TMapResponse.java
TMap API 응답 및 파싱 응답 DTO(레코드) 추가, Swagger 문서화
.../direction/external/tmap/mapper/TMapMapper.java TMap API 응답 파싱 및 변환 매퍼 클래스 추가
.../direction/service/WalkingService.java 워킹 서비스 클래스 및 TMap API 호출-파싱 로직 추가
.../direction/exception/WalkingErrorCase.java 워킹 경로 관련 에러 케이스 정의하는 enum 클래스 추가

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant WalkingController
    participant WalkingService
    participant TMapClient
    participant TMap (External)
    participant TMapMapper

    Client->>WalkingController: GET /api/v1/directions/walking (파라미터 포함)
    WalkingController->>WalkingService: callTMapApi(TMapRequest)
    WalkingService->>TMapClient: response(TMapRequest)
    TMapClient->>TMap: POST /pedestrian route API (TMapRequest, appKey)
    TMap-->>TMapClient: TMapResponse
    TMapClient-->>WalkingService: TMapResponse
    WalkingService->>TMapMapper: parseResponse(TMapResponse)
    TMapMapper-->>WalkingService: TMapParsingResponse
    WalkingService-->>WalkingController: TMapParsingResponse
    WalkingController-->>Client: CommonResponse<TMapParsingResponse>
Loading

Possibly related issues

Suggested reviewers

  • seung-in-Yoo

Poem

🐇
TMap 길 따라 hop hop hop,
걷는 길도 척척 척!
API 부르고, 응답을 파싱,
서비스와 매퍼가 함께 마칭.
WebClient 달려,
길찾기 완료!
코드는 산뜻, 산책은 즐겁도다.
🚶‍♂️🌱

✨ Finishing Touches
  • 📝 Generate Docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 10

🧹 Nitpick comments (5)
src/main/java/com/wayble/server/common/config/WebClientConfig.java (1)

17-20: 기본 WebClient Bean의 명명 개선 필요

현재 webClient라는 일반적인 이름은 다른 WebClient Bean들과 충돌할 가능성이 있습니다. 더 구체적인 이름을 사용하는 것을 고려해보세요.

-public WebClient webClient() {
+public WebClient defaultWebClient() {
src/main/java/com/wayble/server/direction/controller/WalkingController.java (1)

21-33: 입력 검증 추가 고려사항

컨트롤러 구현이 깔끔하고 좋은 패턴을 따르고 있습니다. 다만 입력 검증을 추가하면 더욱 견고해질 것입니다.

입력 검증 추가 고려사항:

 public CommonResponse<TMapParsingResponse> callTMapApi(
-        @RequestParam double startX,
-        @RequestParam double startY,
-        @RequestParam double endX,
-        @RequestParam double endY,
-        @RequestParam String startName,
-        @RequestParam String endName
+        @RequestParam @Valid @DecimalMin("-180") @DecimalMax("180") double startX,
+        @RequestParam @Valid @DecimalMin("-90") @DecimalMax("90") double startY,
+        @RequestParam @Valid @DecimalMin("-180") @DecimalMax("180") double endX,
+        @RequestParam @Valid @DecimalMin("-90") @DecimalMax("90") double endY,
+        @RequestParam @NotBlank String startName,
+        @RequestParam @NotBlank String endName
 ) {
src/main/java/com/wayble/server/direction/external/tmap/dto/response/TMapParsingResponse.java (2)

8-16: (선택) 총 거리·시간은 long 으로 두는 편이 안전합니다
도보 API라도 API 스펙상 totalDistance, totalTime 의 최대값이 명시되어 있지 않다면 int(약 21억) 을 초과할 가능성을 배제할 수 없습니다.
long 으로 확장해 두면 설계 단계에서 다시 손볼 일이 줄어듭니다.


17-23: NULL 필드 제외 설정이 빠져 있습니다
steps 외 다수 필드가 상황에 따라 null 로 반환될 수 있는데, 최상위 record 에 @JsonInclude(JsonInclude.Include.NON_NULL) 이 없으면 모든 null 필드가 그대로 노출됩니다.
API 응답 크기를 줄이고 클라이언트 파싱 오류를 예방하려면 다음과 같이 추가를 권장합니다.

+import com.fasterxml.jackson.annotation.JsonInclude;
 ...
 @Builder
+@JsonInclude(JsonInclude.Include.NON_NULL)
 @Schema(description = "도보 최적 경로 T MAP API")
 public record TMapParsingResponse(
src/main/java/com/wayble/server/direction/external/tmap/dto/response/TMapResponse.java (1)

16-19: Geometry.coordinates 를 List<Object> 로 두면 타입 안정성이 크게 떨어집니다
실제 응답은 [lon, lat] 또는 [[lon, lat], ...] 형태의 숫자 배열이므로
List<List<Double>> 또는 List<Double> 를 다루는 커스텀 DTO(예: CoordinatePath) 로 파싱한 뒤,
후속 매핑 단계에서 도메인 객체로 변환하는 쪽이 타입 에러를 줄이고 IDE 지원을 극대화할 수 있습니다.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0217a39 and d0bed78.

📒 Files selected for processing (12)
  • build.gradle (1 hunks)
  • src/main/java/com/wayble/server/ServerApplication.java (2 hunks)
  • src/main/java/com/wayble/server/common/config/WebClientConfig.java (1 hunks)
  • src/main/java/com/wayble/server/direction/controller/WalkingController.java (1 hunks)
  • src/main/java/com/wayble/server/direction/controller/swagger/WalkingSwagger.java (1 hunks)
  • src/main/java/com/wayble/server/direction/external/tmap/TMapClient.java (1 hunks)
  • src/main/java/com/wayble/server/direction/external/tmap/TMapProperties.java (1 hunks)
  • src/main/java/com/wayble/server/direction/external/tmap/dto/request/TMapRequest.java (1 hunks)
  • src/main/java/com/wayble/server/direction/external/tmap/dto/response/TMapParsingResponse.java (1 hunks)
  • src/main/java/com/wayble/server/direction/external/tmap/dto/response/TMapResponse.java (1 hunks)
  • src/main/java/com/wayble/server/direction/external/tmap/mapper/TMapMapper.java (1 hunks)
  • src/main/java/com/wayble/server/direction/service/WalkingService.java (1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (2)
src/main/java/com/wayble/server/direction/external/tmap/dto/request/TMapRequest.java (1)
src/main/java/com/wayble/server/common/response/CommonResponse.java (1)
  • Builder (8-42)
src/main/java/com/wayble/server/direction/external/tmap/dto/response/TMapParsingResponse.java (1)
src/main/java/com/wayble/server/common/response/CommonResponse.java (1)
  • Builder (8-42)
🔇 Additional comments (3)
build.gradle (1)

54-55: WebFlux 의존성 추가가 적절합니다.

TMap API 호출을 위한 WebClient 사용을 위해 spring-boot-starter-webflux 의존성이 추가되었습니다. 이는 RestTemplate보다 권장되는 현대적인 HTTP 클라이언트 접근법입니다.

src/main/java/com/wayble/server/ServerApplication.java (1)

3-3: TMap 설정 속성 바인딩이 올바르게 구성되었습니다.

@EnableConfigurationProperties(TMapProperties.class) 어노테이션을 통해 TMap 설정 속성 바인딩이 적절히 활성화되었습니다. Spring Boot의 표준 패턴을 잘 따르고 있습니다.

Also applies to: 7-7, 16-16

src/main/java/com/wayble/server/direction/controller/swagger/WalkingSwagger.java (1)

11-31: 잘 구성된 Swagger 인터페이스

API 문서화가 잘 되어 있고, 한국어 설명이 명확합니다. 매개변수 구조도 직관적으로 설계되었습니다.

private final TMapMapper tMapMapper;

public TMapParsingResponse callTMapApi(TMapRequest request) {
TMapResponse response = tMapClient.response(request);
Copy link

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

WebClient의 동기적 사용 방식을 확인하세요.

TMapClient.response() 메서드가 WebClient를 사용하면서 동기적으로 구현되었는지 확인이 필요합니다. WebClient는 기본적으로 비동기이므로 block() 호출 시 스레드 블로킹 이슈가 발생할 수 있습니다.

다음 스크립트로 TMapClient 구현을 확인해보겠습니다:


🏁 Script executed:

#!/bin/bash
# TMapClient의 구현 방식 확인
ast-grep --pattern 'class TMapClient {
  $$$
  response($$$) {
    $$$
  }
  $$$
}'

Length of output: 85


🏁 Script executed:

#!/bin/bash
# TMapClient.java 파일 위치 확인 및 WebClient 사용·block() 호출 여부 검사
file=$(find . -type f -name 'TMapClient.java' | head -n1)
echo "TMapClient 경로: $file"
if [ -z "$file" ]; then
  echo "TMapClient.java 파일을 찾을 수 없습니다."
  exit 1
fi
echo "--- WebClient 사용 위치 ---"
grep -n "WebClient" "$file" || echo "WebClient 키워드 없음"
echo "--- block() 호출 위치 ---"
grep -n "block(" "$file" || echo "block() 호출 없음"

Length of output: 886


WebClient 블로킹 호출 확인 필요

TMapClient.response() 메서드에서 WebClient의 .block() 호출이 확인되어 스레드 풀 블로킹 이슈가 발생할 수 있습니다. 가능한 비동기/reactive 흐름을 유지하거나, 별도 스레드 풀(boundedElastic 등)에서 실행되도록 변경을 검토해주세요.

  • 파일: src/main/java/com/wayble/server/direction/external/tmap/TMapClient.java
    • 25행: .block() 호출
  • 제안
    • bodyToMono(TMapResponse.class)를 반환하도록 수정 후 호출 지점에서 비동기 처리
    • subscribeOn(Schedulers.boundedElastic()) 또는 publishOn 사용
🤖 Prompt for AI Agents
In src/main/java/com/wayble/server/direction/service/WalkingService.java at line
19, the call to tMapClient.response() is blocking due to the use of
WebClient.block() inside that method, which can cause thread pool blocking
issues. Refactor TMapClient.response() to return a Mono<TMapResponse> instead of
blocking, then update this calling code to handle the response asynchronously by
subscribing or chaining reactive operators. Additionally, ensure the reactive
flow uses subscribeOn(Schedulers.boundedElastic()) or publishOn to offload
blocking operations to a separate thread pool.

Copy link
Member

@seung-in-Yoo seung-in-Yoo left a comment

Choose a reason for hiding this comment

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

수고하셨습니다!! 결과는 포인트와 라인으로 구분돼서 포인트 지점에서 실제 존재하는 도로 라인을 따라 경로를 제공해주는건가요??

@zyovn
Copy link
Member Author

zyovn commented Jul 20, 2025

수고하셨습니다!! 결과는 포인트와 라인으로 구분돼서 포인트 지점에서 실제 존재하는 도로 라인을 따라 경로를 제공해주는건가요??

네넵 맞습니다! 해당 포인트부터 실제 존재하는 도로 라인의 위도 경도를 따라 경로를 제공해주는 형태입니다!!

@seung-in-Yoo
Copy link
Member

수고하셨습니다!! 결과는 포인트와 라인으로 구분돼서 포인트 지점에서 실제 존재하는 도로 라인을 따라 경로를 제공해주는건가요??

네넵 맞습니다! 해당 포인트부터 실제 존재하는 도로 라인의 위도 경도를 따라 경로를 제공해주는 형태입니다!!

Tmap API는 사용 안해봤는데 프론트 구현되고나서 실제로 어떤식으로 나오는지 직접 화면으로 보고싶네요 ㅎㅎ 수고하셨습니다 정빈님~!!

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

♻️ Duplicate comments (1)
src/main/java/com/wayble/server/direction/service/WalkingService.java (1)

22-31: WebClient 블로킹 호출로 인한 성능 이슈를 검토하세요.

이전 리뷰에서 지적된 WebClient의 .block() 호출 문제가 여전히 존재할 수 있습니다. 현재 tMapClient.response(request) 호출이 내부적으로 블로킹 방식으로 구현되어 있어 스레드 풀 블로킹 이슈가 발생할 수 있습니다.

비동기 처리를 위한 개선을 고려해보세요:

public Mono<TMapParsingResponse> callTMapApi(TMapRequest request) {
    return tMapClient.response(request)
        .doOnNext(response -> log.info("🎉 T MAP API 호출 성공"))
        .map(tMapMapper::parseResponse)
        .doOnError(e -> log.error("🚨 T MAP API 호출 실패: {}", e.getMessage()))
        .onErrorMap(e -> new ApplicationException(WalkingErrorCase.T_MAP_API_FAILED));
}
🧹 Nitpick comments (1)
src/main/java/com/wayble/server/direction/service/WalkingService.java (1)

25-25: 로깅 메시지에 더 많은 컨텍스트 정보를 추가하세요.

성공 로그에 요청 파라미터나 응답 시간 등의 정보를 포함하면 디버깅과 모니터링에 도움이 됩니다.

log.info("🎉 T MAP API 호출 성공 - startX: {}, startY: {}, endX: {}, endY: {}", 
    request.startX(), request.startY(), request.endX(), request.endY());
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d0bed78 and d1a1dda.

📒 Files selected for processing (4)
  • src/main/java/com/wayble/server/common/config/WebClientConfig.java (1 hunks)
  • src/main/java/com/wayble/server/direction/exception/WalkingErrorCase.java (1 hunks)
  • src/main/java/com/wayble/server/direction/external/tmap/mapper/TMapMapper.java (1 hunks)
  • src/main/java/com/wayble/server/direction/service/WalkingService.java (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • src/main/java/com/wayble/server/direction/exception/WalkingErrorCase.java
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/main/java/com/wayble/server/common/config/WebClientConfig.java
  • src/main/java/com/wayble/server/direction/external/tmap/mapper/TMapMapper.java
🔇 Additional comments (4)
src/main/java/com/wayble/server/direction/service/WalkingService.java (4)

1-12: 임포트 구조가 잘 정리되어 있습니다.

패키지 구조와 임포트가 명확하고 논리적으로 구성되어 있어 코드의 가독성이 좋습니다.


14-17: Spring 어노테이션과 Lombok 설정이 적절합니다.

@Slf4j, @Service, @RequiredArgsConstructor 어노테이션이 올바르게 적용되어 있어 Spring 컨테이너에서 빈으로 관리되고 로깅과 의존성 주입이 적절히 구성되었습니다.


19-20: 의존성 주입이 올바르게 구현되었습니다.

final 키워드와 @RequiredArgsConstructor를 사용하여 불변성을 보장하면서 깔끔한 의존성 주입을 구현했습니다.


28-29: 예외 처리가 개선되었습니다.

이전 리뷰에서 요청된 오류 처리와 로깅이 적절히 구현되어 있고, 커스텀 예외를 통한 에러 케이스 처리도 잘 되어 있습니다.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

💡 feature 기능 구현 및 개발

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants