명세

  • Social media application
    • User -> Posts
    Description Rest API Http Method
    Retrieve all Users /users GET
    Create an Users /users POST
    Retrieve one User /user/{id} GET
    Update an User /user/{id} Patch
    Delete an User /user/{id} DELETE

User 서비스

  • GetMapping
    • /users
      @GetMapping("/users")
      public List<User> retrieveAllUsers() {
          return userService.findAll();
      }
      
    • /users/${id}
      @GetMapping("/users/{id}")
      public User retrieveUser(@PathVariable Integer id) {
          Optional<User> byId = userService.findOne(id);		
          return byId.orElseThrow(()-> {
              throw new UserNotFoundException(String.format("ID[%s] not found", id));			
          }); 
      }
      
      • @PathVariable을 활용하여 URI에 선언된 변수(id)를 가져온다.
      • 예외 처리
        • id에 해당하는 User가 없는 경우 에외 발생
        • Customizing Exception 구현
          @ResponseStatus(HttpStatus.NOT_FOUND)
          public class UserNotFoundException extends RuntimeException{
              public UserNotFoundException() {
                  super();
              }
              public UserNotFoundException(String message) {
                  super(message);
              }
          }
          
          • RuntimeException을 상속받아 구현한다.
          • ResponseStatus를 활용하여 HttpStatus 상태 코드를 지정할 수 있다.
            • 2XX번 대는 정상, 4XX번 대는 Client의 잘못된 요청, 5XX번 대는 서버 측의 문제
        • 예외 Controller 구현
          @RestController
          @ControllerAdvice
          public class CustomizeResponseEntityExceptionHandler extends ResponseEntityExceptionHandler{
              @ExceptionHandler(Exception.class)
              public final ResponseEntity<Object> handleAllException(Exception ex, WebRequest request) {
                  ExceptionResponse exceptionResponse = new ExceptionResponse(LocalDateTime.now(), ex.getMessage(), request.getDescription(false));
                  return new ResponseEntity<Object>(exceptionResponse, HttpStatus.INTERNAL_SERVER_ERROR);
              }
              @ExceptionHandler(UserNotFoundException.class)
              public final ResponseEntity<Object> handleUserNotFoundException(Exception ex, WebRequest request) {
                  ExceptionResponse exceptionResponse = new ExceptionResponse(LocalDateTime.now(), ex.getMessage(), request.getDescription(false));
                  return new ResponseEntity<Object>(exceptionResponse, HttpStatus.NOT_FOUND);
              }
          }
          
          • @ControllerAdvice: 예외 Controller임을 알린다.
          • @ExceptionHandler
            • 예외 발생 시 해당 핸들러가 실행되도록 한다.
            • 발생되는 예외마다 실행되는 핸들러를 지정해줄 수 있다.
  • PostMapping
    • /users

      @PostMapping("/users")
      public ResponseEntity<User> createUser(@Valid @RequestBody User user) {
          User savedUser = userService.save(user);
      
          URI location = ServletUriComponentsBuilder.fromCurrentRequest()
              .path("/{id}")
              .buildAndExpand(savedUser.getId())
              .toUri();
      
          return ResponseEntity.created(location).build();
      }
      
      • ServletUriComponentsBuilder.fromCurrentRequest().path(“/{id}”).buildAndExpand(saveUser.getId()).toUri();
        • 현재 요청 URI(http://localhost:8180/users)을 리턴하며. path로 뒤에 path를 붙여 주며, buildAndExpand로 pathVariable 값을 세팅한다.
      • ReseponseEntity.created(URI).build()
        • HttpStatus.CREATED(201 code) 상태로 return 하며, location header에 지정한 URI로 설정한다.
      • vadliation check
        • 파라미터를 받을 객체에 @Valid를 붙여준다.
        • DAO 객체에 사용하고자 하는 제약 사항을 걸어줄 수 있다.
          • Annotation으로 불가능 한것은 Validator 구현체를 만들어 사용할 수 있다.
          • @InitBinder를 사용하여 요청올 때마다 객체에 대한 검사를 진행할 수 있다.
        @Data
        @NoArgsConstructor @AllArgsConstructor
        @Getter @Setter
        public class User {
          private Integer id;
        		
          @Size(min = 2, message= "이름은 2글자 이상 입력해주세요.")
          private String name;
        		
          @Past
          private LocalDateTime joinDate;
        }
        
        • Errors 객체로 에러를 받거나 Exception Handler를 받을 수 있다.

          @Override
          protected ResponseEntity<Object> handleMethodArgumentNotValid(MethodArgumentNotValidException ex, HttpHeaders headers, HttpStatus status, WebRequest request) {
              ExceptionResponse exceptionResponse = new ExceptionResponse(LocalDateTime.now(), "validation failed", ex.getBindingResult().toString());
              return new ResponseEntity<Object>(exceptionResponse, HttpStatus.BAD_REQUEST);
          }
          // CustomizeResponseEntityExceptionHandler
          // ResponseEntityExceptionHandler의 handlermethodArgumentNotValid 오버라이딩	
          
  • PutMapping
    • /users/id
      @PutMapping("/users/{id}")
      public User updateUser(@PathVariable Integer id, @RequestBody User user) {
          Optional<User> byId = userService.updateUser(id, user);
          return byId.orElseThrow(() -> {
              throw new UserNotFoundException(String.format("ID[%s] not found", id));
          });
      }
      
  • DeleteMapping
    • /users/id
      @DeleteMapping("/users/{id}")
      public void deleteUser(@PathVariable Integer id) {
          userService.deleteById(id).orElseThrow(()-> {
          throw new UserNotFoundException(String.format("ID[%s} not found", id));
          });
      }