-
Notifications
You must be signed in to change notification settings - Fork 2
[Location] 사용자 위치 CRUD 및 Swagger 작성 #95
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
Changes from all commits
41ef309
12c92b2
b49317f
6bbd1d2
c3465af
383cb11
0c93b28
0b01e1d
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 |
|---|---|---|
|
|
@@ -2,27 +2,99 @@ | |
|
|
||
| import com.back.web7_9_codecrete_be.domain.location.dto.KakaoLocalResponse; | ||
| import com.back.web7_9_codecrete_be.domain.location.service.KakaoLocalService; | ||
| import com.back.web7_9_codecrete_be.global.rsData.RsData; | ||
| import io.swagger.v3.oas.annotations.Operation; | ||
| import io.swagger.v3.oas.annotations.Parameter; | ||
| import io.swagger.v3.oas.annotations.tags.Tag; | ||
| import io.swagger.v3.oas.annotations.media.Content; | ||
| import io.swagger.v3.oas.annotations.media.Schema; | ||
| import io.swagger.v3.oas.annotations.responses.ApiResponse; | ||
| import lombok.RequiredArgsConstructor; | ||
| import org.springframework.web.bind.annotation.GetMapping; | ||
| import org.springframework.web.bind.annotation.RequestMapping; | ||
| import org.springframework.web.bind.annotation.RestController; | ||
| import org.springframework.web.bind.annotation.*; | ||
|
|
||
| import java.util.List; | ||
|
|
||
| @Tag(name = "Location - Kakao", description = "카카오 로컬 API 연동(주변 음식점 조회, 좌표→주소 변환) 관련 엔드포인트") | ||
| @RestController | ||
| @RequestMapping("/api/test") | ||
| @RequestMapping("/api/v1/location/kakao") | ||
| @RequiredArgsConstructor | ||
| public class KakaoTestController { | ||
|
|
||
| private final KakaoLocalService kakaoLocalService; | ||
|
|
||
| @GetMapping("/kakao-restaurants") | ||
| @Operation( | ||
| summary = "주변 음식점 조회(테스트)", | ||
| description = "테스트용 하드코딩 좌표(서울 시청 근처)로 카카오 로컬에서 주변 음식점을 조회합니다., 하드코딩 좌표 : lat - 37.5665, lng -126.9780" | ||
| ) | ||
| @ApiResponse(responseCode = "200", description = "조회 성공", | ||
| content = @Content(schema = @Schema(implementation = KakaoLocalResponse.Document.class))) | ||
| @GetMapping("/restaurants") | ||
|
|
||
| public List<KakaoLocalResponse.Document> testKakaoRestaurants() { | ||
|
|
||
| // ✅ 테스트용 하드코딩 좌표 (서울 시청 근처) | ||
| double lat = 37.5665; | ||
| double lng = 126.9780; | ||
|
|
||
| return kakaoLocalService.searchNearbyRestaurants(lat, lng); | ||
| } | ||
|
|
||
| @Operation( | ||
| summary = "주변 음식점 조회(테스트)", | ||
| description = "테스트용 좌표(서울 시청 근처)로 카카오 로컬에서 주변 음식점을 조회합니다, 좌표는 입력하면 됩니다." + | ||
| "예시 : http://localhost:8080/api/v1/location/kakao/restaurant?lat=37.5665&lng=126.9780" | ||
| ) | ||
|
Collaborator
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. 설명 + 예시를 통해 친절하게 표현하신 부분이 보기 좋네요
Collaborator
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. 감사합니다! |
||
| @PostMapping("/restaurant") | ||
| public List<KakaoLocalResponse.Document> KakaoRestaurants( | ||
| @RequestParam double lat, | ||
| @RequestParam double lng | ||
| ){ | ||
| return kakaoLocalService.searchNearbyRestaurants(lat, lng); | ||
| } | ||
|
|
||
| @Operation( | ||
| summary = "주변 카페 조회(테스트)", | ||
|
Collaborator
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. 혹시 카페 조회 메서드가 2개인 이유가 있을까용??
Collaborator
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. 하나는 테스트용이라서 해당 부분은 바로 수정해놓겠습니다! |
||
| description = "테스트용 하드코딩 좌표(서울 시청 근처)로 카카오 로컬에서 주변 카페를 조회합니다., 하드코딩 좌표 : lat - 37.5665, lng -126.9780" | ||
| ) | ||
| @ApiResponse(responseCode = "200", description = "조회 성공", | ||
| content = @Content(schema = @Schema(implementation = KakaoLocalResponse.Document.class))) | ||
| @GetMapping("/cafes") | ||
| public List<KakaoLocalResponse.Document> testKakaoCafes() { | ||
|
|
||
| double lat = 37.5665; | ||
| double lng = 126.9780; | ||
|
|
||
| return kakaoLocalService.searchNearbyCafes(lat, lng); | ||
| } | ||
|
|
||
| @Operation( | ||
| summary = "주변 카페 조회(테스트)", | ||
| description = "테스트용 좌표(서울 시청 근처)로 카카오 로컬에서 주변 카페를 조회합니다, 좌표는 입력하면 됩니다." + | ||
| "예시 : http://localhost:8080/api/v1/location/kakao/cafes?lat=37.5665&lng=126.9780" | ||
| ) | ||
| @PostMapping("/cafes") | ||
| public List<KakaoLocalResponse.Document> KakaoCafes( | ||
| @RequestParam double lat, | ||
| @RequestParam double lng | ||
| ){ | ||
| return kakaoLocalService.searchNearbyCafes(lat, lng); | ||
| } | ||
|
|
||
|
|
||
| @Operation( | ||
| summary = "좌표를 주소로 변환", | ||
| description = "위도(lat), 경도(lon)를 받아 카카오 API로 주소명(address_name)을 반환합니다." | ||
| ) | ||
| @ApiResponse(responseCode = "200", description = "변환 성공", | ||
| content = @Content(schema = @Schema(implementation = RsData.class))) | ||
| @GetMapping("/coord2address") | ||
| public RsData<String> coord2Address( | ||
| @Parameter(description = "위도(latitude)", example = "37.5665", required = true) | ||
| @RequestParam double lat, | ||
|
|
||
| @Parameter(description = "경도(longitude)", example = "126.9780", required = true) | ||
| @RequestParam double lon | ||
| ) { | ||
| String addressName = kakaoLocalService.coordinateToAddressName(lat, lon); | ||
| return RsData.success("좌표를 주소로 변환했습니다.", addressName); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,15 +1,59 @@ | ||
| package com.back.web7_9_codecrete_be.domain.location.controller; | ||
|
|
||
| import com.back.web7_9_codecrete_be.domain.location.dto.request.LocationRequestDto; | ||
| import com.back.web7_9_codecrete_be.domain.location.dto.response.LocationResponseDto; | ||
| import com.back.web7_9_codecrete_be.domain.location.service.LocationService; | ||
| import com.back.web7_9_codecrete_be.domain.users.entity.User; | ||
| import com.back.web7_9_codecrete_be.global.rq.Rq; | ||
| import com.back.web7_9_codecrete_be.global.rsData.RsData; | ||
| import io.swagger.v3.oas.annotations.Operation; | ||
| import io.swagger.v3.oas.annotations.tags.Tag; | ||
| import lombok.RequiredArgsConstructor; | ||
| import org.springframework.web.bind.annotation.RequestMapping; | ||
| import org.springframework.web.bind.annotation.RestController; | ||
| import org.springframework.web.bind.annotation.*; | ||
|
|
||
| @RestController | ||
| @RequestMapping("/api/v1/location") | ||
| @RequestMapping("/api/v1/location/my") | ||
| @RequiredArgsConstructor | ||
| @Tag(name = "Location", description = "위치(Location) 관련 API") | ||
| public class LocationController { | ||
|
|
||
| private final LocationService locationService; | ||
| private final Rq rq; | ||
|
|
||
| @GetMapping() | ||
| @Operation(summary = "사용자 위치 조회", description = "사용자의 위치 정보를 조회합니다.") | ||
| public RsData<LocationResponseDto> getMyLocation( | ||
| ){ | ||
| User user = rq.getUser(); | ||
| return RsData.success("내 위치정보를 조회합니다", locationService.getLocation(user)); | ||
| } | ||
|
|
||
|
|
||
| @PostMapping() | ||
| @Operation(summary = "사용자 위치 저장", description = "사용자의 위치 정보를 저장합니다.") | ||
| public RsData<LocationResponseDto> saveMyLocation( | ||
| @RequestBody LocationRequestDto locationRequestDto | ||
| ){ | ||
| User user = rq.getUser(); | ||
| return RsData.success("내 위치정보를 저장했습니다.", locationService.saveLocation(locationRequestDto, user)); | ||
| } | ||
|
|
||
|
|
||
| @PatchMapping | ||
| @Operation(summary = "사용자 위치 수정", description = "사용자의 위치 정보를 수정합니다.") | ||
| public RsData<LocationResponseDto> modifyMyLocation( | ||
| @RequestBody LocationRequestDto locationRequestDto | ||
| ){ | ||
| User user = rq.getUser(); | ||
| return RsData.success("내 위치정보를 수정했습니다.", locationService.modifyLocation(locationRequestDto, user)); | ||
| } | ||
|
|
||
| @DeleteMapping | ||
| @Operation(summary = "사용자 위치 삭제", description = "사용자의 위치 정보를 삭제합니다.") | ||
| public RsData<Void> deleteMyLocation( | ||
| ){ | ||
| User user = rq.getUser(); | ||
| locationService.removeLocation(user); | ||
| return RsData.success("내 위치정보를 삭제했습니다.", null); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,26 +1,74 @@ | ||
| package com.back.web7_9_codecrete_be.domain.location.controller; | ||
|
|
||
| import com.back.web7_9_codecrete_be.domain.location.service.TmapService; | ||
| import io.swagger.v3.oas.annotations.Operation; | ||
| import io.swagger.v3.oas.annotations.Parameter; | ||
| import io.swagger.v3.oas.annotations.responses.ApiResponse; | ||
| import io.swagger.v3.oas.annotations.media.Content; | ||
| import io.swagger.v3.oas.annotations.media.Schema; | ||
| import io.swagger.v3.oas.annotations.tags.Tag; | ||
| import lombok.RequiredArgsConstructor; | ||
| import org.springframework.web.bind.annotation.GetMapping; | ||
| import org.springframework.web.bind.annotation.RequestMapping; | ||
| import org.springframework.web.bind.annotation.RequestParam; | ||
| import org.springframework.web.bind.annotation.RestController; | ||
| import org.springframework.web.bind.annotation.*; | ||
|
|
||
| @Tag( | ||
| name = "Location - Tmap", | ||
| description = "Tmap 대중교통 길찾기 API 연동" | ||
| ) | ||
| @RestController | ||
| @RequiredArgsConstructor | ||
| @RequestMapping("/api/tmap") | ||
| @RequestMapping("/api/v1/location") | ||
| public class TmapController { | ||
|
|
||
| private final TmapService tmapService; | ||
|
|
||
| @GetMapping("/transit") | ||
| @Operation( | ||
| summary = "대중교통 경로 조회", | ||
| description = """ | ||
| 출발지(startX, startY)와 도착지(endX, endY) 좌표를 기반으로 | ||
| Tmap 대중교통 API를 호출하여 경로 정보를 조회합니다. | ||
| """ | ||
| ) | ||
| @ApiResponse( | ||
| responseCode = "200", | ||
| description = "경로 조회 성공", | ||
| content = @Content( | ||
| mediaType = "application/json", | ||
| schema = @Schema( | ||
| description = "Tmap 대중교통 경로 조회 결과(JSON 문자열)" | ||
| ) | ||
| ) | ||
| ) | ||
| @GetMapping("/tmap/transit") | ||
| public String getTransit( | ||
|
|
||
| @Parameter( | ||
| description = "출발지 경도 (longitude)", | ||
| example = "126.9780", | ||
| required = true | ||
| ) | ||
| @RequestParam double startX, | ||
|
|
||
| @Parameter( | ||
| description = "출발지 위도 (latitude)", | ||
| example = "37.5665", | ||
| required = true | ||
| ) | ||
| @RequestParam double startY, | ||
|
|
||
| @Parameter( | ||
| description = "도착지 경도 (longitude)", | ||
| example = "127.0276", | ||
| required = true | ||
| ) | ||
| @RequestParam double endX, | ||
|
|
||
| @Parameter( | ||
| description = "도착지 위도 (latitude)", | ||
| example = "37.4979", | ||
| required = true | ||
| ) | ||
| @RequestParam double endY | ||
| ) { | ||
| return tmapService.getRoute(startX, startY, endX, endY); | ||
| } | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,71 @@ | ||
| package com.back.web7_9_codecrete_be.domain.location.dto; | ||
|
|
||
| import io.swagger.v3.oas.annotations.media.Schema; | ||
| import lombok.Data; | ||
|
|
||
| import java.util.List; | ||
|
|
||
| @Data | ||
| @Schema(description = "카카오 좌표 → 주소 변환 응답 DTO") | ||
| public class KakaoCoordinateResponse { | ||
|
|
||
| @Schema( | ||
| description = "주소 변환 결과 목록", | ||
| example = "[]" | ||
| ) | ||
| private List<Document> documents; | ||
|
|
||
| @Data | ||
| @Schema(description = "좌표 변환 결과 문서") | ||
| public static class Document { | ||
|
|
||
| @Schema(description = "지번 주소 정보") | ||
| private Address address; | ||
|
|
||
| @Schema(description = "도로명 주소 정보") | ||
| private RoadAddress road_address; | ||
| } | ||
|
|
||
| @Data | ||
| @Schema(description = "지번 주소 상세 정보") | ||
| public static class Address { | ||
|
|
||
| @Schema(description = "전체 지번 주소", example = "서울 중구 태평로1가 31") | ||
| private String address_name; | ||
|
|
||
| @Schema(description = "시/도", example = "서울") | ||
| private String region_1depth_name; | ||
|
|
||
| @Schema(description = "구", example = "중구") | ||
| private String region_2depth_name; | ||
|
|
||
| @Schema(description = "동", example = "태평로1가") | ||
| private String region_3depth_name; | ||
|
|
||
| @Schema(description = "산 여부 (Y/N)", example = "N") | ||
| private String mountain_yn; | ||
|
|
||
| @Schema(description = "본번", example = "31") | ||
| private String main_address_no; | ||
|
|
||
| @Schema(description = "부번", example = "0") | ||
| private String sub_address_no; | ||
| } | ||
|
|
||
| @Data | ||
| @Schema(description = "도로명 주소 상세 정보") | ||
| public static class RoadAddress { | ||
|
|
||
| @Schema(description = "전체 도로명 주소", example = "서울 중구 세종대로 110") | ||
| private String address_name; | ||
|
|
||
| @Schema(description = "도로명", example = "세종대로") | ||
| private String road_name; | ||
|
|
||
| @Schema(description = "건물명", example = "서울시청") | ||
| private String building_name; | ||
|
|
||
| @Schema(description = "우편번호", example = "04524") | ||
| private String zone_no; | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,20 +1,37 @@ | ||
| package com.back.web7_9_codecrete_be.domain.location.dto; | ||
|
|
||
| import io.swagger.v3.oas.annotations.media.Schema; | ||
| import lombok.Data; | ||
|
|
||
| import java.util.List; | ||
|
|
||
| @Data | ||
| @Schema(description = "카카오 로컬 API 장소 검색 응답 DTO") | ||
| public class KakaoLocalResponse { | ||
|
|
||
| @Schema(description = "장소 검색 결과 목록") | ||
| private List<Document> documents; | ||
|
|
||
| @Data | ||
| @Schema(description = "카카오 장소 정보") | ||
| public static class Document { | ||
|
|
||
| @Schema(description = "장소명", example = "디라이프 스타일키친 광화문점") | ||
| private String place_name; | ||
| private String x; // longitude | ||
| private String y; // latitude | ||
|
|
||
| @Schema(description = "경도(longitude)", example = "126.97826128583668") | ||
| private String x; | ||
|
|
||
| @Schema(description = "위도(latitude)", example = "37.56842610180289") | ||
| private String y; | ||
|
|
||
| @Schema(description = "도로명 주소", example = "서울 중구 세종대로 136") | ||
| private String road_address_name; | ||
|
|
||
| @Schema(description = "지번 주소", example = "서울 중구 태평로1가 84") | ||
| private String address_name; | ||
|
|
||
| @Schema(description = "카카오 장소 상세 URL", example = "http://place.map.kakao.com/444516464") | ||
| private String place_url; | ||
| } | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,15 +1,31 @@ | ||
| package com.back.web7_9_codecrete_be.domain.location.dto; | ||
|
|
||
| import io.swagger.v3.oas.annotations.media.Schema; | ||
| import lombok.Data; | ||
|
|
||
| @Data | ||
| @Schema(description = "Tmap 대중교통 경로 조회 요청 DTO") | ||
| public class TmapResponse { | ||
|
|
||
| @Schema(description = "출발지 경도 (longitude)", example = "126.9780") | ||
| private String startX; | ||
|
|
||
| @Schema(description = "출발지 위도 (latitude)", example = "37.5665") | ||
| private String startY; | ||
|
|
||
| @Schema(description = "도착지 경도 (longitude)", example = "127.0276") | ||
| private String endX; | ||
|
|
||
| @Schema(description = "도착지 위도 (latitude)", example = "37.4979") | ||
| private String endY; | ||
| private int count; //최대 응답 결과 개수 | ||
| private String format; //출력포멧 : jsom, xml | ||
|
|
||
| @Schema(description = "최대 응답 결과 개수", example = "5") | ||
| private int count; | ||
|
|
||
| @Schema( | ||
| description = "응답 포맷 (json / xml)", | ||
| example = "json", | ||
| allowableValues = {"json", "xml"} | ||
| ) | ||
| private String format; | ||
| } |
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.
넵 알겠습니다!