Develop20 (2) 백엔드가 위치 기반 서비스 개발하며 알아야할 지오코딩 위치 기반 서비스를 개발하기 전 지오코딩과 리버스 지오코딩에 대해 알아보자. 지오코딩: 사용자가 입력한 주소를 정확한 위도와 경도의 좌표로 변환 리버스 지오코딩: 사용자가 입력한 위도와 경도의 좌표를 정확한 주소로 변환 이전 글에서 언급했듯, 위치 기반 서비스의 백엔드는 지역별 혹은 거리(반경) 내 데이터 조회를 고려해야한다. 지오코딩은 주소를 특정 위치의 좌표로 변환하므로, 반경 내 조회에 필수적이며, 리버스 지오코딩은 사용자의 현재 위치를 주소로 변환하므로, 사용자가 위치한 지역 내 조회에 필수적이다. 따라서, 위치 기반 서비스의 백엔드에서 위치 데이터를 효율적으로 관리하기 위해, 지오코딩과 리버스 지오코딩(이후, 지오코딩)이 매우 중요한 역할을 한다는 사실을 알 수 있다. 그렇다면, 이렇게 필수적인.. 2024. 3. 12. 1. 위치 기반 서비스를 위한 사전 지식 배경 최근에 토이 프로젝트에서 위치 기반 서비스에 대한 관심이 증가하고 있다. 우아한테크코스 5기만 하더라도 진행된 24개 프로젝트 중 7개 팀이 위치(좌표)를 기반으로 한 데이터 정리 기능을 포함하고 있었다. 이 글은 괜찮을지도 프로젝트를 수행하는 과정(혹은 그 이후에)에서, 위치 기반 서비스에 관련된 지식을 배우면서 알게 된 유용한 정보 중 사전에 알고 있었다면 도움이 됐을 내용들을 정리한 것이다. 다른 개발자들, 또는 미래의 나 자신이 위치 기반 서비스를 다룰 때 이 글을 통해 도움을 받기를 바란다. 위치 기반 서비스에서 백엔드는 무엇을 신경써야할까? 백엔드는 웹 개발 중 사용자가 요구하는 정보를 저장, 관리, 그리고 제공하는 역할을 수행한다. 위치 기반 서비스의 경우엔, 사용자가 요구하는 정보가 .. 2024. 3. 11. 제목은 Producer - Consumer 패턴 구현하기로 하겠습니다. 근데 이제 BlockingQueue를 곁들인... 배경 실습으로 배우는 선착순 이벤트 시스템을 학습하면서, 분산 환경에서 선착순으로 발생하는 동시성 문제를 해결하는 방법을 학습했습니다. Kafka나 Redis를 이용하는 방식은 물론 여러모로 장점이 많지만, 토이 프로젝트나, 간단한 어플리케이션 등에서 사용하기엔 비용적인 측면에서 부담이 클 수 있습니다. 그로 인해, Redis와 Kafka를 각각 AtomicInteger와 BlockingQueue로 대체하여 자바 코드로 구현했습니다. 전체 코드는 GitHub Repository에서 확인 가능합니다. Coupon @Entity @NoArgsConstructor(access = AccessLevel.PROTECTED) @Getter public class Coupon { @Id @GeneratedValue(.. 2024. 3. 7. [Spring Web MVC] Exceptions - @ControllerAdvice @ControllerAdvice 예시 코드 @ControllerAdvice public class GlobalExceptionHandler { @ExceptionHandler(CustomException.class) public ResponseEntity handleCustomException(CustomException ex) { return ResponseEntity.status(HttpStatus.BAD_REQUEST). 정상 코드와 예외 처리 코드 분리 가능 @ExceptionHandler만 사용 시, 정상 코드와 예외 처리 코드가 하나의 컨트롤러 위치 @Component로 메타 어노테이션이 지정되어 있으므로 component Scanning을 통해 Spring 빈으로 등록 가능 대상으로 지정한 .. 2023. 4. 17. [Spring Web MVC] Exceptions - @ExceptionHandler @ExceptionHandler @Controller public class MyController { @GetMapping("/example") public String exampleMethod() { // 여기에 코드 작성 throw new CustomException("사용자 정의 예외입니다"); } @ExceptionHandler(CustomException.class) public ResponseEntity handleCustomException(CustomException ex) { return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(ex.getMessage()); } } ExceptionHandlerExceptionResolver 스프링 기.. 2023. 4. 17. [Spring Web MVC] Handler Methods - Return Values Return Values String 뷰 이름을 나타내는 문자열을 반환하면, 스프링 웹 MVC는 뷰 리졸버(ViewResolver)를 사용하여 해당 뷰를 찾아 렌더링한 후 클라이언트에게 전달한다. 뷰 템플릿 기본 경로 src/main/resources/templates @ResponseBody 메서드에 사용되며, 반환 값이 HttpMessageConverter를 통해 response body으로 직렬화된다. 클래스 수준에서도 지원되며, 이 경우 모든 컨트롤러 메서드에 상속된다. 비동기 요청과 반응형 타입과 함께 @ResponseBody사용 가능 @ResponseStatus(HttpStatus.OK) 애노테이션을 통해 응답 코드 설정 가능 MVC Config의 메시지 변환기(Message Converter.. 2023. 4. 17. [Spring Web MVC] Handler Methods - MethodArgument @RequestParam Servlet 요청 파라미터(query parameter 또는 form data)를 메소드의 파라미터에 바인딩할 때 사용되는 어노테이션 (주로 단일 요청 파라미터) 동작 원리 @RequestParam("petId") int id → request.getParameter("username") 쿼리 파라미터 이름이 변수 이름과 같으면 @RequestParam(name="xx") 생략 가능 String , int , Integer 등의 단순 타입이면 @RequestParam 도 생략 가능 String이 아닌 경우 자동으로 타입 변환(Type Conversion) 적용 파라미터 타입을 배열이나 리스트로 선언 가능 required 옵션 파라미터 필수 여부를 결정한다. (기본값 = true.. 2023. 4. 17. [Spring Web MVC] Request Mapping - consumes, produces Media Types 일반적으로 사용되는 미디어 유형에 대한 상수 제공 APPLICATION_JSON_VALUE APPLICATION_XML_VALUE 문자 집합 지정 가능 부정 표현식 지원 ex) !text/plain은 텍스트/일반 이외의 모든 Content-Type 의미 Producible Media Types // produces 속성을 이용한 방법 @GetMapping(path = "/pets/{petId}", produces = "application/json") @ResponseBody public Pet getPet(@PathVariable String petId) { // ... } Accept request header와 컨트롤러 메서드가 생성하는 Content-Type 목록을 기반으로 .. 2023. 4. 17. [Spring Web MVC] Request Mapping - Parameters, headers Parameters, headers 요청 매개변수 조건에 따라 요청 매핑의 범위를 좁힐 수 있다. 요청 매개변수(myParam)가 있는지, 없는지(!myParam) 또는 특정 값(myParam=myValue)이 있는지 테스트할 수 있다. // 매개변수 - 특정 값 존재 여부 테스트 @GetMapping(path = "/pets/{petId}", params = "myParam=myValue") public void findPet(@PathVariable String petId) { // ... } 요청 헤더 조건에 따라서도 요청 매핑의 범위를 좁힐 수 있다. // 헤더 - 특정 값 존재 여부 테스트 @GetMapping(path = "/pets/{petId}", headers = "myHeader=myV.. 2023. 4. 17. 이전 1 2 3 다음