-
Notifications
You must be signed in to change notification settings - Fork 2
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
GET: /api/v1/traffics/{trafficId} 컨트롤러 구현 #15
Changes from all commits
cc77914
36420c7
e678e6b
cba9dbc
933452d
795df88
1c957a4
ffe99c5
818d62a
c3b8ee1
5ca4918
877f44f
99e708e
1623e00
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,35 @@ | ||
package com.walking.api.converter; | ||
|
||
import com.walking.api.service.dto.PredictedData; | ||
import com.walking.api.web.dto.response.detail.PointDetail; | ||
import com.walking.api.web.dto.response.detail.TrafficDetail; | ||
import com.walking.data.entity.traffic.TrafficEntity; | ||
|
||
public final class TrafficDetailConverter { | ||
|
||
private TrafficDetailConverter() {} | ||
|
||
/** | ||
* PredictedData를 기반으로 TrafficDetail를 생성합니다. | ||
* | ||
* @param predictedData 사이클 정보 와 현재 색상 및 잔여시간을 예측한 데이터 | ||
* @return 예측 값을 바탕으로 만든 TrafficDetail | ||
*/ | ||
public static TrafficDetail execute(PredictedData predictedData) { | ||
|
||
TrafficEntity trafficEntity = predictedData.getTraffic(); | ||
|
||
return TrafficDetail.builder() | ||
.id(trafficEntity.getId()) | ||
.color(predictedData.getCurrentColor().toString()) | ||
.timeLeft(predictedData.getCurrentTimeLeft()) | ||
.point( | ||
PointDetail.builder().lng(trafficEntity.getLng()).lat(trafficEntity.getLat()).build()) | ||
.redCycle(predictedData.getRedCycle()) | ||
.greenCycle(predictedData.getGreenCycle()) | ||
.detail(TrafficDetailInfoConverter.execute(trafficEntity)) | ||
.isFavorite(false) | ||
.viewName(trafficEntity.getName()) | ||
.build(); | ||
} | ||
} | ||
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
package com.walking.api.converter; | ||
|
||
import com.fasterxml.jackson.core.JsonProcessingException; | ||
import com.fasterxml.jackson.databind.JsonMappingException; | ||
import com.fasterxml.jackson.databind.ObjectMapper; | ||
import com.walking.api.web.dto.response.detail.TrafficDetailInfo; | ||
import com.walking.data.entity.traffic.TrafficEntity; | ||
|
||
public final class TrafficDetailInfoConverter { | ||
|
||
private TrafficDetailInfoConverter() {} | ||
|
||
/** | ||
* api.traffic_detail 의 detail 값(JSON)을 파싱하여 TrafficDetailInfo 로 변환합니다. | ||
* | ||
* @param trafficEntity | ||
* @return | ||
*/ | ||
public static TrafficDetailInfo execute(TrafficEntity trafficEntity) { | ||
ObjectMapper objectMapper = new ObjectMapper(); | ||
TrafficDetailInfo trafficDetailInfo = | ||
TrafficDetailInfo.builder().trafficId(-1L).apiSource("ERROR").direction("ERROR").build(); | ||
try { | ||
trafficDetailInfo = | ||
objectMapper.readValue(trafficEntity.getDetail(), TrafficDetailInfo.class); | ||
} catch (JsonMappingException e) { | ||
throw new RuntimeException("Convert to TrafficDetailInfo fail", e); | ||
} catch (JsonProcessingException e) { | ||
throw new RuntimeException("Convert to TrafficDetailInfo fail", e); | ||
} | ||
|
||
return trafficDetailInfo; | ||
} | ||
} | ||
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. 이 코드는 주로 안전성 측면에서 개선이 필요합니다.
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. 이 코드 페치는 JSON 데이터를 파싱하여 TrafficDetailInfo 객체로 변환하는 역할을 합니다. 코드 리뷰 및 개선 제안은 다음과 같습니다:
위 개선점을 참고하여 코드를 보완하거나 수정하실지 고려해보세요. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,13 @@ | ||
package com.walking.api.repository.member; | ||
package com.walking.api.repository.traffic; | ||
|
||
import com.walking.data.entity.member.MemberEntity; | ||
import com.walking.data.entity.member.TrafficFavoritesEntity; | ||
import java.util.List; | ||
import org.springframework.data.jpa.repository.JpaRepository; | ||
import org.springframework.stereotype.Repository; | ||
|
||
@Repository | ||
public interface TrafficFavoritesRepository extends JpaRepository<TrafficFavoritesEntity, Long> {} | ||
public interface TrafficFavoritesRepository extends JpaRepository<TrafficFavoritesEntity, Long> { | ||
|
||
List<TrafficFavoritesEntity> findByMemberFk(MemberEntity memberFk); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
package com.walking.api.service.traffic; | ||
|
||
import com.walking.api.repository.traffic.TrafficFavoritesRepository; | ||
import com.walking.data.entity.member.MemberEntity; | ||
import com.walking.data.entity.member.TrafficFavoritesEntity; | ||
import java.util.List; | ||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.stereotype.Service; | ||
|
||
@Service | ||
@RequiredArgsConstructor | ||
public class ReadTrafficFavoritesService { | ||
|
||
private final TrafficFavoritesRepository trafficFavoritesRepository; | ||
|
||
public List<TrafficFavoritesEntity> executeByMemberFk(MemberEntity member) { | ||
return trafficFavoritesRepository.findByMemberFk(member); | ||
} | ||
} | ||
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. 이 코드 조각은 작고 깔끔합니다. 하지만 몇 가지 주의해야 할 점이 있습니다:
이외에는 코드 품질이 높고 목적에 맞는 구현이라고 할 수 있습니다. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
package com.walking.api.service.traffic; | ||
|
||
import com.walking.api.repository.traffic.TrafficRepository; | ||
import com.walking.data.entity.traffic.TrafficEntity; | ||
import java.util.List; | ||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.stereotype.Service; | ||
|
||
@Service | ||
@RequiredArgsConstructor | ||
public class ReadTrafficService { | ||
|
||
private final TrafficRepository trafficRepository; | ||
|
||
public TrafficEntity executeById(Long trafficId) { | ||
return trafficRepository.findById(trafficId).orElseThrow(); | ||
} | ||
|
||
public List<TrafficEntity> executeByIds(List<Long> trafficIds) { | ||
return trafficRepository.findByIds(trafficIds); | ||
} | ||
} | ||
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. 이 코드는 대체로 깔끔하며 효율적으로 보입니다. 그러나 개선을 위해 몇 가지 제안 사항이 있습니다:
여기까지가 간단한 코드 리뷰입니다. 부분적인 응용 및 수정은 필요에 따라 적용하시면 좋을 것입니다. |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -146,9 +146,9 @@ private static RouteDetailResponse getSampleRouteDetailResponse() { | |
.viewName("후문") | ||
.point(PointDetail.builder().lat(BACK_DOOR_LAT).lng(BACK_DOOR_LNG).build()) | ||
.color("red") | ||
.remainTime(10L) | ||
.redCycle(30L) | ||
.greenCycle(30L) | ||
.timeLeft(10f) | ||
.redCycle(30f) | ||
.greenCycle(30f) | ||
.build())) | ||
.paths( | ||
List.of( | ||
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. 이 코드 조각의 변경 내용을 간략히 검토하겠습니다: 버그 위험:
개선 제안:
부가적 의견: |
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,11 @@ | ||
package com.walking.api.web.controller.traffic; | ||
|
||
import com.walking.api.converter.TrafficDetailConverter; | ||
import com.walking.api.security.authentication.token.TokenUserDetails; | ||
import com.walking.api.service.TrafficIntegrationPredictService; | ||
import com.walking.api.service.dto.PredictedData; | ||
import com.walking.api.service.dto.request.IntegrationPredictRequestDto; | ||
import com.walking.api.service.dto.response.IntegrationPredictResponseDto; | ||
import com.walking.api.web.dto.request.point.OptionalTrafficPointParam; | ||
import com.walking.api.web.dto.request.point.OptionalViewPointParam; | ||
import com.walking.api.web.dto.request.traffic.FavoriteTrafficBody; | ||
|
@@ -17,13 +22,15 @@ | |
import com.walking.api.web.support.MessageCode; | ||
import java.time.LocalDateTime; | ||
import java.util.List; | ||
import java.util.Map; | ||
import java.util.Objects; | ||
import javax.validation.Valid; | ||
import javax.validation.constraints.Min; | ||
import lombok.RequiredArgsConstructor; | ||
import lombok.extern.slf4j.Slf4j; | ||
import org.springframework.http.HttpStatus; | ||
import org.springframework.security.core.annotation.AuthenticationPrincipal; | ||
import org.springframework.transaction.annotation.Transactional; | ||
import org.springframework.validation.annotation.Validated; | ||
import org.springframework.web.bind.annotation.DeleteMapping; | ||
import org.springframework.web.bind.annotation.GetMapping; | ||
|
@@ -41,6 +48,8 @@ | |
@RequiredArgsConstructor | ||
public class TrafficController { | ||
|
||
private final TrafficIntegrationPredictService integrationPredictService; | ||
|
||
static double TF_BACK_DOOR_LAT = 35.178501; | ||
static double TF_BACK_DOOR_LNG = 126.912083; | ||
static double TF_BACK_THREE_LAT = 35.175841; | ||
|
@@ -76,11 +85,20 @@ public ApiResponse<ApiResponse.SuccessBody<SearchTrafficsResponse>> searchTraffi | |
} | ||
|
||
@GetMapping("/{trafficId}") | ||
@Transactional | ||
public ApiResponse<ApiResponse.SuccessBody<BrowseTrafficsResponse>> browseTraffic( | ||
@PathVariable Long trafficId) { | ||
// todo implement | ||
log.info("Traffic browse trafficId: {}", trafficId); | ||
BrowseTrafficsResponse response = getBrowseTrafficsResponse(); | ||
IntegrationPredictResponseDto integrationPredictedResponse = | ||
integrationPredictService.execute( | ||
IntegrationPredictRequestDto.builder().trafficIds(List.of(trafficId)).build()); | ||
|
||
Map<Long, PredictedData> predictedDataMap = integrationPredictedResponse.getPredictedDataMap(); | ||
PredictedData predictedData = predictedDataMap.get(trafficId); | ||
TrafficDetail trafficDetail = TrafficDetailConverter.execute(predictedData); | ||
BrowseTrafficsResponse response = | ||
BrowseTrafficsResponse.builder().traffic(trafficDetail).build(); | ||
return ApiResponseGenerator.success(response, HttpStatus.OK, MessageCode.SUCCESS); | ||
} | ||
|
||
|
@@ -151,9 +169,9 @@ private static SearchTrafficsResponse getSearchViewTrafficsResponse() { | |
.lng(TF_BACK_DOOR_LNG) | ||
.build()) | ||
.color("red") | ||
.remainTime(10L) | ||
.redCycle(30L) | ||
.greenCycle(30L) | ||
.timeLeft(10f) | ||
.redCycle(30f) | ||
.greenCycle(30f) | ||
.build(), | ||
TrafficDetail.builder() | ||
.id(2L) | ||
|
@@ -171,9 +189,9 @@ private static SearchTrafficsResponse getSearchViewTrafficsResponse() { | |
.lng(TF_BACK_THREE_LNG) | ||
.build()) | ||
.color("green") | ||
.remainTime(20L) | ||
.redCycle(30L) | ||
.greenCycle(30L) | ||
.timeLeft(20f) | ||
.redCycle(30f) | ||
.greenCycle(30f) | ||
.build(), | ||
TrafficDetail.builder() | ||
.id(3L) | ||
|
@@ -188,9 +206,9 @@ private static SearchTrafficsResponse getSearchViewTrafficsResponse() { | |
.point( | ||
PointDetail.builder().lat(TF_CHANPUNG_LAT).lng(TF_CHANPUNG_LNG).build()) | ||
.color("red") | ||
.remainTime(10L) | ||
.redCycle(30L) | ||
.greenCycle(30L) | ||
.timeLeft(10f) | ||
.redCycle(30f) | ||
.greenCycle(30f) | ||
.build(), | ||
TrafficDetail.builder() | ||
.id(4L) | ||
|
@@ -204,9 +222,9 @@ private static SearchTrafficsResponse getSearchViewTrafficsResponse() { | |
.viewName("쿠쿠") | ||
.point(PointDetail.builder().lat(TF_CUCU_LAT).lng(TF_CUCU_LNG).build()) | ||
.color("green") | ||
.remainTime(20L) | ||
.redCycle(30L) | ||
.greenCycle(30L) | ||
.timeLeft(20f) | ||
.redCycle(30f) | ||
.greenCycle(30f) | ||
.build())) | ||
.build(); | ||
|
||
|
@@ -234,9 +252,9 @@ private static SearchTrafficsResponse getSearchTrafficsResponse() { | |
.lng(TF_BACK_DOOR_LNG) | ||
.build()) | ||
.color("red") | ||
.remainTime(10L) | ||
.redCycle(30L) | ||
.greenCycle(30L) | ||
.timeLeft(10f) | ||
.redCycle(30f) | ||
.greenCycle(30f) | ||
.build())) | ||
.build(); | ||
|
||
|
@@ -260,9 +278,9 @@ private static BrowseTrafficsResponse getBrowseTrafficsResponse() { | |
.point( | ||
PointDetail.builder().lat(TF_BACK_DOOR_LAT).lng(TF_BACK_DOOR_LNG).build()) | ||
.color("red") | ||
.remainTime(10L) | ||
.redCycle(30L) | ||
.greenCycle(30L) | ||
.timeLeft(10f) | ||
.redCycle(30f) | ||
.greenCycle(30f) | ||
.build()) | ||
.build(); | ||
|
||
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. 이 코드는 다음과 같은 개선 사항 및 버그 위험에 직면할 수 있습니다:
미리 감사합니다. |
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -17,10 +17,9 @@ | |
public class TrafficDetail { | ||
|
||
private Long id; | ||
private String state; | ||
private Long remainTime; | ||
private Long greenCycle; | ||
private Long redCycle; | ||
private Float timeLeft; | ||
private Float greenCycle; | ||
private Float redCycle; | ||
private PointDetail point; | ||
private String color; | ||
private TrafficDetailInfo detail; | ||
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. 코드 리뷰:
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -232,7 +232,7 @@ void searchTrafficsWithTrafficParam() throws Exception { | |
@DisplayName("GET /{trafficId} 신호등 정보 조회 - 신호등 ID로 조회") | ||
void browseTraffic() throws Exception { | ||
mockMvc | ||
.perform(get(BASE_URL + "/{trafficId}", 1).contentType(MediaType.APPLICATION_JSON)) | ||
.perform(get(BASE_URL + "/{trafficId}", 3).contentType(MediaType.APPLICATION_JSON)) | ||
.andExpect(status().is2xxSuccessful()) | ||
.andDo( | ||
document( | ||
|
@@ -246,7 +246,7 @@ void browseTraffic() throws Exception { | |
new ParameterDescriptorWithType("trafficId") | ||
.type(SimpleType.NUMBER) | ||
.description("신호등 ID") | ||
.defaultValue(1L)) | ||
.defaultValue(3L)) | ||
.responseSchema(Schema.schema("BrowseTrafficResponse")) | ||
.responseFields( | ||
Description.common( | ||
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. 후기:
|
||
|
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.
코드를 살펴보니 다음과 같은 개선점과 버그 위험이 있을 수 있습니다:
TrafficDetailConverter
클래스:TrafficEntity
에서 반환된 ID는null
일 수 있으므로id(trafficEntity.getId())
부분에서null
체크가 필요합니다.코드 품질 및 가독성:
일반적인 개선사항:
null
값의 처리 방법을 고려해야 합니다.TrafficDetail
생성을 담당하는 클래스와 관련된 테스트 케이스를 작성하는 것이 좋습니다.확장성:
개선사항 및 버그 리스크를 고려하거나 추가적인 예외 처리 등을 고려하면 좋겠습니다.