Back-end/Spring

[Spring] User Service API 추가

shoney9254 2022. 11. 6. 14:07
반응형

유저에 관한 서비스 정의 내용

 

파일 구조

User Domain 생성

User.java

package com.example.restfulwebservice.user;

import lombok.AllArgsConstructor;
import lombok.Data;

import java.util.Date;

@Data
@AllArgsConstructor
public class User {
    //lombok으로 프로퍼티만 만들어도 됨
    private Integer id;
    private String name;
    private Date joinDate;
}

 

GET 사용방법

UserController.java

package com.example.restfulwebservice.user;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
public class UserController {
    private UserDaoService service;

    //의존성을 생성자를 통해서 연결한다.
    public UserController(UserDaoService service) {
        this.service = service;
    }

    @GetMapping("/users")
    public List<User> retrieveAllUsers() {
        return service.findAll();
    }

    @GetMapping("/user/{id}")
    public User retrieveUser(@PathVariable int id) { //알아서 인티저로 변경해서 사용하려면 형을 정확하게 입력해ㅝ야함
        return service.findOne(id);
    }
}

UserDaoService

package com.example.restfulwebservice.user;

import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service //어노테이션 추가해야함 빈의 용도를 정확하게 입력해야 다른쪽에서 의존 가능
public class UserDaoService {
    private static List<User>users= new ArrayList<>();

    private static intusersCount=3;

    static{
users.add(new User(1, "Kenneth", new Date()));
users.add(new User(2, "Alice", new Date()));
users.add(new User(3, "Elena", new Date()));
    }

    public List<User> findAll(){
        returnusers;
    }

    public User save(User user) {
        if (user.getId() == null) {
            user.setId(++usersCount);
        }
users.add(user);

        return user;
    }

    public User findOne(int id) {
        for (User user :users) {
            if (user.getId() == id) {
                return user;
            }
        }

        return null;
    }
}

 

DAO

  • DAO(Data Access Object) 는 데이터베이스의 data에 접근하기 위한 객체입니다. DataBase에 접근 하기 위한 로직 & 비지니스 로직을 분리하기 위해 사용합니다.

DTO

  • DTO(Data Transfer Object) 는 계층 간 데이터 교환을 하기 위해 사용하는 객체로, DTO는 로직을 가지지 않는 순수한 데이터 객체(getter & setter 만 가진 클래스)입니다.
  • 유저가 입력한 데이터를 DB에 넣는 과정을 보겠습니다.
    • 유저가 자신의 브라우저에서 데이터를 입력하여 form에 있는 데이터를 DTO에 넣어서 전송합니다.
    • 해당 DTO를 받은 서버가 DAO를 이용하여 데이터베이스로 데이터를 집어넣습니다.

VO

  • VO(Value Object) 값 오브젝트로써 값을 위해 쓰입니다. read-Only 특징(사용하는 도중에 변경 불가능하며 오직 읽기만 가능)을 가집니다.
  • DTO와 유사하지만 DTO는 setter를 가지고 있어 값이 변할 수 있습니다.

 

RequestBody를 사용해서 사용자를 추가하는 API 만들어보자

 

POST 만들기

@RequestBody 어노테이션을 이용해서 POST 함수를 호출할 때 바디 값을 매개변수로 전달할 수 있다.

 

UserController.java

@PostMapping("/users") // 체크하는 순서는 Post인지 먼저 체크하고, uri를 체크해서 이쪽으로 오게됨
public ResponseEntity createUser(@RequestBody User user) { //오브젝트 형식의 데이터를 전달하려면 @RequestBody가 필요함
    User savedUser = service.save(user);

    URI location = ServletUriComponentsBuilder.fromCurrentRequest()
            .path("/{id}")
            .buildAndExpand(savedUser.getId())
            .toUri();

    return ResponseEntity.created(location).build();
}

ResponseEntity를 사용해서 결과 Status를 201로 바꿀 수 있다.

그리고 location에 URI 정보를 넣어서 POST, GET uri 마다 결과 Response가 다르게 나온다는 것을 확인할 수 있다.

Exception Handling

익셉션 핸들링을 하기 위해서 유저에 먼저 UserNotFoundException을 만든다.

UserNotFoundException.java

package com.example.restfulwebservice.user;

import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus;

// HTTP Status code
// 2xx -> ok
// 4xx -> 클라이언트가 잘못했을 때
// 5xx -> 서버측 오류
@ResponseStatus(HttpStatus.NOT_FOUND)
public class UserNotFoundException extends RuntimeException {
    public UserNotFoundException(String message) {
        super(message);
    }
}

CustomizedResponseEntityExceptionHandler.java

package com.example.restfulwebservice.exception;

import com.example.restfulwebservice.user.UserNotFoundException;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;

import java.util.Date;

@RestController
@ControllerAdvice //모든 컨틀로가 실행될때 이 어노테이션을 가지고 있는 빈이 먼저 실행된다.AOP
public class CustomizedResponseEntityExceptionHandler extends ResponseEntityExceptionHandler {

    @ExceptionHandler(Exception.class)
    public final ResponseEntity<Object> handleAllException(Exception ex, WebRequest request) {
        ExceptionResponse exceptionResponse =
                new ExceptionResponse(new Date(), ex.getMessage(), request.getDescription(false));

        return new ResponseEntity(exceptionResponse, HttpStatus.INTERNAL_SERVER_ERROR);
    }

    @ExceptionHandler(UserNotFoundException.class)
    public final ResponseEntity<Object> handleUserNotFoundException(Exception ex, WebRequest request) {
        ExceptionResponse exceptionResponse =
                new ExceptionResponse(new Date(), ex.getMessage(), request.getDescription(false));

        return new ResponseEntity(exceptionResponse, HttpStatus.NOT_FOUND);
    }
}

 

DELETE

UserDaoService.java

public User deleteById(int id) {
    Iterator<User> iterator =users.iterator();

    while (iterator.hasNext()) {
        User user = iterator.next();

        if (user.getId() == id) {
            iterator.remove();
            return user;
        }
    }

    return null;
}

이터레이터를 사용해서 while 적용

UserController.java

@DeleteMapping("/users/{id}")
public void deleteUser(@PathVariable int id){
    User user = service.deleteById(id);

    if (user == null) {
        throw new UserNotFoundException(String.format("ID[%s] not found",id));
    }
}

 

PUT 사용

UserDaoService.java

public User udateById(int id, User user){
    User udateUser = findOne(id);
    if (udateUser != null) {
        udateUser.setName(user.getName());
        udateUser.setJoinDate(new Date());
    }
    return udateUser;
}

UserController.java

@PutMapping("/users/{id}")
public User updateUser(@PathVariable int id, @RequestBody User user) {
    User updatedUser = service.udateById(id, user);
    if (updatedUser == null) {
        throw new UserNotFoundException(String.format("ID[%s] not found",id));
    }
    return updatedUser;

}

고객 id는 uri를 통해 받아야 하기 때문에, @PathVariable를 사용

고객의 수정 정보는 객체를 통해 받아야 하기 때문에, @RequestBody 를 사용

 

반응형