들어가며
게시판 기능인데 근처에 거주하고 있는 사람의 글을 조회할 수 있는 기능이 필요해서 게시글을 저장할때와 조회할때 위치를 반영해서 조회와 저장하도록 구현했습니다.
Tool
Spring boot 버전 2.7.7
Naver Cloud Maps
Naver Cloud Platform에서 Service 이용신청하기
저는 위도, 경도를 이용해서 위치를 찾아낼 수 있는 Reverse Geocoding API를 사용했습니다.
API요청은 가이드대로 요청하였습니다.
https://api.ncloud-docs.com/docs/ai-naver-mapsreversegeocoding
일단 사용자 위치를 저장하고 조회할 수 있는 기능을 먼저 구현했습니다.
위도와 경도는 클라이언트에서 받아온 뒤 위치를 저장하고 조회하는 기능을 구현했습니다.
클라이언트에서 받아온 위도와 경도로 위에서 등록한 Naver Server에 요청을 보내서 해당 주소를 받아올 수 있습니다.
public void createLocation(Member member, PostRequestDTO.LocationDTO request){
String coords = request.getLongitude() + "," + request.getLatitude();
NaverGeoResponse naverGeoResponse = naverGeoFeignClient.generateLocation("coordsToaddr",coords,"epsg:4326","json","legalcode");
Optional<Location> location = locationRepository.findByAddress(naverGeoResponse.getResults().get(0).getRegion().getArea3().getName());
if(!location.isPresent()) {
Location newLocation = Location.builder()
.latitude(request.getLatitude())
.longitude(request.getLongitude())
.address(naverGeoResponse.getResults().get(0).getRegion().getArea3().getName())
.member(member)
.build();
locationRepository.save(newLocation);
}
}
조회는 저장한 위치를 불러왔습니다.
public List<Location> getLocationList(Member member){
return locationRepository.findAllByMember(member);
}
Post를 작성할 때 위치도 같이 저장해서 조회할 때 사용자의 현 주소(동 단위)를 가진 Post를 조회할 수 있도록 구현했습니다.
위치 조회를 통해 얻은 위치 id를 request parameter로 넘겨주면 해당 위치 범위에서 작성한 post를 조회할 수 있도록 구현했습니다.(rquest parameter로 null인 경우는 전체 조회되도록 했습니다.)
//controller
@GetMapping("/")
@Operation(summary = "커뮤니티 글 조회 API", description = "커뮤니티에서 글 조회하는 api입니다.postType: 나눔, 레시피, 빈값(전체 조회) ")
@Parameters(value = {
@Parameter(name = "lastIndex", description = "lastIndex 첫 조회는 0이고 스크롤 내릴때마다 마지막 index 입력하시면 됩니다. 맨 처음인 경우 Null"),
@Parameter(name = "postType", description = "나눔, 레시피, 선택하지 않으면 전체가 조회됩니다."),
@Parameter(name = "locationId", description = "위치 조회 해서 나온 현재 위치 id를 입력하면 됩니다. Null인 경우 전체 조회")
})
public ResponseDTO<PostResponseDTO.PostListDTO> getPostList(Authentication auth,
@RequestParam(value = "lastIndex", required = false) Long lastIndex,
@RequestParam(value = "postType", required = false) PostTopicType postTopicType,
@RequestParam(value = "locationId",required = false) Long locationId ){
Member member = memberQueryService.findMemberById(Long.valueOf(auth.getName().toString())).orElseThrow(() -> new MemberHandler(ErrorStatus.MEMBER_NOT_FOUND));
if(lastIndex == null){
lastIndex = 0L;
}
List<Post> posts = postService.getPostList(lastIndex,postTopicType,locationId);
return ResponseDTO.onSuccess(PostConverter.toPostList(posts, member));
}
//service
public List<Post> getPostList(Long lastIndex, PostTopicType postTopicType, Long locationId){
Location location;
if(locationId == null){
location = null;
}else{
location = locationRepository.findById(locationId).orElseThrow(()->new PostHandler(ErrorStatus.LOCATION_NOT_FOUND));
}
return postRepository.findPostList(lastIndex, postTopicType, location);
}
//Repository
public interface PostRepository extends JpaRepository<Post, Long> {
@Query("SELECT p FROM Post p WHERE (:postTopicType IS NULL OR p.topic = :postTopicType) AND p.id > :lastIndex AND(:location IS NULL OR p.location = :location) ORDER BY p.id ASC")
List<Post> findPostList(Long lastIndex, PostTopicType postTopicType, Location location);
}
'Dev' 카테고리의 다른 글
과도한 트래픽에 대한 방어하기 (2) | 2024.12.04 |
---|---|
GCP에 ElasticSearch 띄워서 검색 기능 구현하기 (2) | 2024.12.04 |
fcm 이용해서 앱 푸쉬 구현 (0) | 2024.12.04 |
소켓 통신(채팅방 구현) (0) | 2024.12.04 |
OCR로 영수증 데이터 가져와서 식품 데이터 분류하기(분류 모델 만들기) + Trouble shooting (0) | 2024.12.04 |