Skip to content

Commit bf38622

Browse files
Merge pull request #95 from prgrms-web-devcourse-final-project/feat/#60
[Location] 사용자 위치 CRUD 및 Swagger 작성
2 parents eb8fb5c + 0b01e1d commit bf38622

14 files changed

Lines changed: 531 additions & 23 deletions

File tree

src/main/java/com/back/web7_9_codecrete_be/domain/location/controller/KakaoTestController.java

Lines changed: 78 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,27 +2,99 @@
22

33
import com.back.web7_9_codecrete_be.domain.location.dto.KakaoLocalResponse;
44
import com.back.web7_9_codecrete_be.domain.location.service.KakaoLocalService;
5+
import com.back.web7_9_codecrete_be.global.rsData.RsData;
6+
import io.swagger.v3.oas.annotations.Operation;
7+
import io.swagger.v3.oas.annotations.Parameter;
8+
import io.swagger.v3.oas.annotations.tags.Tag;
9+
import io.swagger.v3.oas.annotations.media.Content;
10+
import io.swagger.v3.oas.annotations.media.Schema;
11+
import io.swagger.v3.oas.annotations.responses.ApiResponse;
512
import lombok.RequiredArgsConstructor;
6-
import org.springframework.web.bind.annotation.GetMapping;
7-
import org.springframework.web.bind.annotation.RequestMapping;
8-
import org.springframework.web.bind.annotation.RestController;
13+
import org.springframework.web.bind.annotation.*;
914

1015
import java.util.List;
1116

17+
@Tag(name = "Location - Kakao", description = "카카오 로컬 API 연동(주변 음식점 조회, 좌표→주소 변환) 관련 엔드포인트")
1218
@RestController
13-
@RequestMapping("/api/test")
19+
@RequestMapping("/api/v1/location/kakao")
1420
@RequiredArgsConstructor
1521
public class KakaoTestController {
1622

1723
private final KakaoLocalService kakaoLocalService;
1824

19-
@GetMapping("/kakao-restaurants")
25+
@Operation(
26+
summary = "주변 음식점 조회(테스트)",
27+
description = "테스트용 하드코딩 좌표(서울 시청 근처)로 카카오 로컬에서 주변 음식점을 조회합니다., 하드코딩 좌표 : lat - 37.5665, lng -126.9780"
28+
)
29+
@ApiResponse(responseCode = "200", description = "조회 성공",
30+
content = @Content(schema = @Schema(implementation = KakaoLocalResponse.Document.class)))
31+
@GetMapping("/restaurants")
32+
2033
public List<KakaoLocalResponse.Document> testKakaoRestaurants() {
2134

22-
// ✅ 테스트용 하드코딩 좌표 (서울 시청 근처)
2335
double lat = 37.5665;
2436
double lng = 126.9780;
2537

2638
return kakaoLocalService.searchNearbyRestaurants(lat, lng);
2739
}
40+
41+
@Operation(
42+
summary = "주변 음식점 조회(테스트)",
43+
description = "테스트용 좌표(서울 시청 근처)로 카카오 로컬에서 주변 음식점을 조회합니다, 좌표는 입력하면 됩니다." +
44+
"예시 : http://localhost:8080/api/v1/location/kakao/restaurant?lat=37.5665&lng=126.9780"
45+
)
46+
@PostMapping("/restaurant")
47+
public List<KakaoLocalResponse.Document> KakaoRestaurants(
48+
@RequestParam double lat,
49+
@RequestParam double lng
50+
){
51+
return kakaoLocalService.searchNearbyRestaurants(lat, lng);
52+
}
53+
54+
@Operation(
55+
summary = "주변 카페 조회(테스트)",
56+
description = "테스트용 하드코딩 좌표(서울 시청 근처)로 카카오 로컬에서 주변 카페를 조회합니다., 하드코딩 좌표 : lat - 37.5665, lng -126.9780"
57+
)
58+
@ApiResponse(responseCode = "200", description = "조회 성공",
59+
content = @Content(schema = @Schema(implementation = KakaoLocalResponse.Document.class)))
60+
@GetMapping("/cafes")
61+
public List<KakaoLocalResponse.Document> testKakaoCafes() {
62+
63+
double lat = 37.5665;
64+
double lng = 126.9780;
65+
66+
return kakaoLocalService.searchNearbyCafes(lat, lng);
67+
}
68+
69+
@Operation(
70+
summary = "주변 카페 조회(테스트)",
71+
description = "테스트용 좌표(서울 시청 근처)로 카카오 로컬에서 주변 카페를 조회합니다, 좌표는 입력하면 됩니다." +
72+
"예시 : http://localhost:8080/api/v1/location/kakao/cafes?lat=37.5665&lng=126.9780"
73+
)
74+
@PostMapping("/cafes")
75+
public List<KakaoLocalResponse.Document> KakaoCafes(
76+
@RequestParam double lat,
77+
@RequestParam double lng
78+
){
79+
return kakaoLocalService.searchNearbyCafes(lat, lng);
80+
}
81+
82+
83+
@Operation(
84+
summary = "좌표를 주소로 변환",
85+
description = "위도(lat), 경도(lon)를 받아 카카오 API로 주소명(address_name)을 반환합니다."
86+
)
87+
@ApiResponse(responseCode = "200", description = "변환 성공",
88+
content = @Content(schema = @Schema(implementation = RsData.class)))
89+
@GetMapping("/coord2address")
90+
public RsData<String> coord2Address(
91+
@Parameter(description = "위도(latitude)", example = "37.5665", required = true)
92+
@RequestParam double lat,
93+
94+
@Parameter(description = "경도(longitude)", example = "126.9780", required = true)
95+
@RequestParam double lon
96+
) {
97+
String addressName = kakaoLocalService.coordinateToAddressName(lat, lon);
98+
return RsData.success("좌표를 주소로 변환했습니다.", addressName);
99+
}
28100
}
Lines changed: 47 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,59 @@
11
package com.back.web7_9_codecrete_be.domain.location.controller;
22

3+
import com.back.web7_9_codecrete_be.domain.location.dto.request.LocationRequestDto;
4+
import com.back.web7_9_codecrete_be.domain.location.dto.response.LocationResponseDto;
35
import com.back.web7_9_codecrete_be.domain.location.service.LocationService;
6+
import com.back.web7_9_codecrete_be.domain.users.entity.User;
7+
import com.back.web7_9_codecrete_be.global.rq.Rq;
8+
import com.back.web7_9_codecrete_be.global.rsData.RsData;
9+
import io.swagger.v3.oas.annotations.Operation;
10+
import io.swagger.v3.oas.annotations.tags.Tag;
411
import lombok.RequiredArgsConstructor;
5-
import org.springframework.web.bind.annotation.RequestMapping;
6-
import org.springframework.web.bind.annotation.RestController;
12+
import org.springframework.web.bind.annotation.*;
713

814
@RestController
9-
@RequestMapping("/api/v1/location")
15+
@RequestMapping("/api/v1/location/my")
1016
@RequiredArgsConstructor
17+
@Tag(name = "Location", description = "위치(Location) 관련 API")
1118
public class LocationController {
1219

1320
private final LocationService locationService;
21+
private final Rq rq;
1422

23+
@GetMapping()
24+
@Operation(summary = "사용자 위치 조회", description = "사용자의 위치 정보를 조회합니다.")
25+
public RsData<LocationResponseDto> getMyLocation(
26+
){
27+
User user = rq.getUser();
28+
return RsData.success("내 위치정보를 조회합니다", locationService.getLocation(user));
29+
}
30+
31+
32+
@PostMapping()
33+
@Operation(summary = "사용자 위치 저장", description = "사용자의 위치 정보를 저장합니다.")
34+
public RsData<LocationResponseDto> saveMyLocation(
35+
@RequestBody LocationRequestDto locationRequestDto
36+
){
37+
User user = rq.getUser();
38+
return RsData.success("내 위치정보를 저장했습니다.", locationService.saveLocation(locationRequestDto, user));
39+
}
40+
41+
42+
@PatchMapping
43+
@Operation(summary = "사용자 위치 수정", description = "사용자의 위치 정보를 수정합니다.")
44+
public RsData<LocationResponseDto> modifyMyLocation(
45+
@RequestBody LocationRequestDto locationRequestDto
46+
){
47+
User user = rq.getUser();
48+
return RsData.success("내 위치정보를 수정했습니다.", locationService.modifyLocation(locationRequestDto, user));
49+
}
50+
51+
@DeleteMapping
52+
@Operation(summary = "사용자 위치 삭제", description = "사용자의 위치 정보를 삭제합니다.")
53+
public RsData<Void> deleteMyLocation(
54+
){
55+
User user = rq.getUser();
56+
locationService.removeLocation(user);
57+
return RsData.success("내 위치정보를 삭제했습니다.", null);
58+
}
1559
}
Lines changed: 55 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,74 @@
11
package com.back.web7_9_codecrete_be.domain.location.controller;
22

33
import com.back.web7_9_codecrete_be.domain.location.service.TmapService;
4+
import io.swagger.v3.oas.annotations.Operation;
5+
import io.swagger.v3.oas.annotations.Parameter;
6+
import io.swagger.v3.oas.annotations.responses.ApiResponse;
7+
import io.swagger.v3.oas.annotations.media.Content;
8+
import io.swagger.v3.oas.annotations.media.Schema;
9+
import io.swagger.v3.oas.annotations.tags.Tag;
410
import lombok.RequiredArgsConstructor;
5-
import org.springframework.web.bind.annotation.GetMapping;
6-
import org.springframework.web.bind.annotation.RequestMapping;
7-
import org.springframework.web.bind.annotation.RequestParam;
8-
import org.springframework.web.bind.annotation.RestController;
11+
import org.springframework.web.bind.annotation.*;
912

13+
@Tag(
14+
name = "Location - Tmap",
15+
description = "Tmap 대중교통 길찾기 API 연동"
16+
)
1017
@RestController
1118
@RequiredArgsConstructor
12-
@RequestMapping("/api/tmap")
19+
@RequestMapping("/api/v1/location")
1320
public class TmapController {
1421

1522
private final TmapService tmapService;
1623

17-
@GetMapping("/transit")
24+
@Operation(
25+
summary = "대중교통 경로 조회",
26+
description = """
27+
출발지(startX, startY)와 도착지(endX, endY) 좌표를 기반으로
28+
Tmap 대중교통 API를 호출하여 경로 정보를 조회합니다.
29+
"""
30+
)
31+
@ApiResponse(
32+
responseCode = "200",
33+
description = "경로 조회 성공",
34+
content = @Content(
35+
mediaType = "application/json",
36+
schema = @Schema(
37+
description = "Tmap 대중교통 경로 조회 결과(JSON 문자열)"
38+
)
39+
)
40+
)
41+
@GetMapping("/tmap/transit")
1842
public String getTransit(
43+
44+
@Parameter(
45+
description = "출발지 경도 (longitude)",
46+
example = "126.9780",
47+
required = true
48+
)
1949
@RequestParam double startX,
50+
51+
@Parameter(
52+
description = "출발지 위도 (latitude)",
53+
example = "37.5665",
54+
required = true
55+
)
2056
@RequestParam double startY,
57+
58+
@Parameter(
59+
description = "도착지 경도 (longitude)",
60+
example = "127.0276",
61+
required = true
62+
)
2163
@RequestParam double endX,
64+
65+
@Parameter(
66+
description = "도착지 위도 (latitude)",
67+
example = "37.4979",
68+
required = true
69+
)
2270
@RequestParam double endY
2371
) {
2472
return tmapService.getRoute(startX, startY, endX, endY);
2573
}
26-
}
74+
}
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
package com.back.web7_9_codecrete_be.domain.location.dto;
2+
3+
import io.swagger.v3.oas.annotations.media.Schema;
4+
import lombok.Data;
5+
6+
import java.util.List;
7+
8+
@Data
9+
@Schema(description = "카카오 좌표 → 주소 변환 응답 DTO")
10+
public class KakaoCoordinateResponse {
11+
12+
@Schema(
13+
description = "주소 변환 결과 목록",
14+
example = "[]"
15+
)
16+
private List<Document> documents;
17+
18+
@Data
19+
@Schema(description = "좌표 변환 결과 문서")
20+
public static class Document {
21+
22+
@Schema(description = "지번 주소 정보")
23+
private Address address;
24+
25+
@Schema(description = "도로명 주소 정보")
26+
private RoadAddress road_address;
27+
}
28+
29+
@Data
30+
@Schema(description = "지번 주소 상세 정보")
31+
public static class Address {
32+
33+
@Schema(description = "전체 지번 주소", example = "서울 중구 태평로1가 31")
34+
private String address_name;
35+
36+
@Schema(description = "시/도", example = "서울")
37+
private String region_1depth_name;
38+
39+
@Schema(description = "구", example = "중구")
40+
private String region_2depth_name;
41+
42+
@Schema(description = "동", example = "태평로1가")
43+
private String region_3depth_name;
44+
45+
@Schema(description = "산 여부 (Y/N)", example = "N")
46+
private String mountain_yn;
47+
48+
@Schema(description = "본번", example = "31")
49+
private String main_address_no;
50+
51+
@Schema(description = "부번", example = "0")
52+
private String sub_address_no;
53+
}
54+
55+
@Data
56+
@Schema(description = "도로명 주소 상세 정보")
57+
public static class RoadAddress {
58+
59+
@Schema(description = "전체 도로명 주소", example = "서울 중구 세종대로 110")
60+
private String address_name;
61+
62+
@Schema(description = "도로명", example = "세종대로")
63+
private String road_name;
64+
65+
@Schema(description = "건물명", example = "서울시청")
66+
private String building_name;
67+
68+
@Schema(description = "우편번호", example = "04524")
69+
private String zone_no;
70+
}
71+
}
Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,37 @@
11
package com.back.web7_9_codecrete_be.domain.location.dto;
22

3+
import io.swagger.v3.oas.annotations.media.Schema;
34
import lombok.Data;
45

56
import java.util.List;
67

78
@Data
9+
@Schema(description = "카카오 로컬 API 장소 검색 응답 DTO")
810
public class KakaoLocalResponse {
11+
12+
@Schema(description = "장소 검색 결과 목록")
913
private List<Document> documents;
1014

1115
@Data
16+
@Schema(description = "카카오 장소 정보")
1217
public static class Document {
18+
19+
@Schema(description = "장소명", example = "디라이프 스타일키친 광화문점")
1320
private String place_name;
14-
private String x; // longitude
15-
private String y; // latitude
21+
22+
@Schema(description = "경도(longitude)", example = "126.97826128583668")
23+
private String x;
24+
25+
@Schema(description = "위도(latitude)", example = "37.56842610180289")
26+
private String y;
27+
28+
@Schema(description = "도로명 주소", example = "서울 중구 세종대로 136")
1629
private String road_address_name;
30+
31+
@Schema(description = "지번 주소", example = "서울 중구 태평로1가 84")
1732
private String address_name;
33+
34+
@Schema(description = "카카오 장소 상세 URL", example = "http://place.map.kakao.com/444516464")
1835
private String place_url;
1936
}
20-
}
37+
}
Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,31 @@
11
package com.back.web7_9_codecrete_be.domain.location.dto;
22

3+
import io.swagger.v3.oas.annotations.media.Schema;
34
import lombok.Data;
45

56
@Data
7+
@Schema(description = "Tmap 대중교통 경로 조회 요청 DTO")
68
public class TmapResponse {
79

10+
@Schema(description = "출발지 경도 (longitude)", example = "126.9780")
811
private String startX;
12+
13+
@Schema(description = "출발지 위도 (latitude)", example = "37.5665")
914
private String startY;
15+
16+
@Schema(description = "도착지 경도 (longitude)", example = "127.0276")
1017
private String endX;
18+
19+
@Schema(description = "도착지 위도 (latitude)", example = "37.4979")
1120
private String endY;
12-
private int count; //최대 응답 결과 개수
13-
private String format; //출력포멧 : jsom, xml
1421

22+
@Schema(description = "최대 응답 결과 개수", example = "5")
23+
private int count;
24+
25+
@Schema(
26+
description = "응답 포맷 (json / xml)",
27+
example = "json",
28+
allowableValues = {"json", "xml"}
29+
)
30+
private String format;
1531
}

0 commit comments

Comments
 (0)