Spring 게시판 9 - 회원API

춤인형의 개발일지·2025년 1월 17일

Spring실습

목록 보기
10/40

회원API

  1. DTO설계
//request
public record UserRequest(
        String userName,
        String userInfoId,
        String userPassword,
        String userEmail
) {
}

//response
public record UserResponse(
        Long id,
        String userName,
        String userId,
        String userPassword,
        String userEmail
) {
}

//request - 이름 조회용 요청
public record UserProfileRequest(
        Long id,
        String userName
) {
}

//response - 이름 조회용 응답
public record UserProfileResponse(
        Long id,
        String userName
) {
}
  1. API설계 가지고 controller 작성
@RestController
public class UserInfoController {

    private final UserService userService;

    public UserInfoController(UserService userService) {
        this.userService = userService;
    }

    @PostMapping("/users/infos")
    public UserResponse save(@Valid @RequestBody UserRequest userRequest){
        return userService.save(userRequest);
    }

    //사용자의 프로필 - 이름만 보이는 상태
    @GetMapping("/users")
    public UserProfileResponse findById(@Valid @RequestBody UserProfileRequest userProfileRequest){
        return userService.findByProfile(userProfileRequest);
    }

    //사용자의 프로필 조회 - 아이디/비번
    @GetMapping("/users/profiles")
    public UserResponse findByUserProfile(@RequestParam Long userId){
        return userService.findByUserProfileDetail(userId);
    }

    @PutMapping("/users/{userId}")
    public UserResponse update(@PathVariable Long userId, @Valid @RequestBody UserRequest userRequest){
        return userService.update(userId, userRequest);
    }

    @DeleteMapping("/users/{userId}")
    public void delete(@PathVariable Long userId){
        userService.deleteById(userId);
    }
}
  1. Repository 작성
public interface UserRepository extends JpaRepository<UserInfo, Long> {
}
  1. controller의 service함수 작성
@Service
public class UserService {

    private final UserRepository userRepository;

    public UserService(UserRepository userRepository) {
        this.userRepository = userRepository;
    }

    public UserResponse save(UserRequest userRequest) {
        UserInfo user = userRepository.save(new UserInfo(
                userRequest.userName(),
                userRequest.userInfoId(),
                userRequest.userPassword(),
                userRequest.userEmail()));

        return new UserResponse(
                user.getId(),
                user.getUserName(),
                user.getUserId(),
                user.getPassWord(),
                user.getEmail());
    }

    public UserResponse findByUserProfileDetail(Long userId) {
        UserInfo user = userRepository.findById(userId)
                .orElseThrow(() -> new NoSuchElementException("찾는 사용자가 없습니다."));
        return new UserResponse(
                userId,
                user.getUserName(),
                user.getUserId(),
                user.getPassWord(),
                user.getEmail()
        );
    }

    public UserProfileResponse findByProfile(UserProfileRequest userProfileRequest) {
        userRepository.findById(userProfileRequest.id())
                .orElseThrow(() -> new NoSuchElementException("찾는 사용자가 없습니다."));
        return new UserProfileResponse(userProfileRequest.id(), userProfileRequest.userName());
    }

    @Transactional
    public UserResponse update(Long userId, UserRequest userRequest) {
        UserInfo user = userRepository.findById(userId)
                .orElseThrow(() -> new NoSuchElementException("찾는 사용자가 없습니다"));
        user.setUserId(userRequest.userInfoId());
        user.setUserName(userRequest.userName());
        user.setPassWord(userRequest.userPassword());
        user.setEmail(userRequest.userEmail());
        return new UserResponse(
                userId,
                userRequest.getUserName(),
                userRequest.getUserId(),
                userRequest.getPassWord(),
                userRequest.getEmail());
    }

    public void deleteById(Long userId) {
        userRepository.findById(userId)
                .orElseThrow(()->new NoSuchElementException("찾는 사용자가 없습니다."));
        userRepository.deleteById(userId);
    }
}
  1. Entity작성
@Entity
public class UserInfo {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String userName;

    private String userId;

    private String passWord;

    private String email;

    protected UserInfo() {
    }

    public UserInfo(String userName, String userId, String passWord, String email) {
        this.userName = userName;
        this.userId = userId;
        this.passWord = passWord;
        this.email = email;
    }

    public Long getId() {
        return id;
    }

    public String getUserName() {
        return userName;
    }

    public String getUserId() {
        return userId;
    }

    public String getPassWord() {
        return passWord;
    }

    public String getEmail() {
        return email;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public void setUserId(String userId) {
        this.userId = userId;
    }

    public void setPassWord(String passWord) {
        this.passWord = passWord;
    }

    public void setEmail(String email) {
        this.email = email;
    }
}

Test 코드 작성하기

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class UserTest extends AcceptanceTest {

    @LocalServerPort
    int port;

    @BeforeEach
    void setUp() {
        RestAssured.port = port;
    }

    @Test
    void 사용자_생성() {
        UserResponse 사용자1 = RestAssured
                .given().log().all()
                .contentType(ContentType.JSON)
                .body(new UserRequest("추민영", "chuchu", "123", "chu@naver.com"))
                .when()
                .post("/users/infos")
                .then().log().all()
                .statusCode(200)
                .extract()
                .as(UserResponse.class);

        assertThat(사용자1).isNotNull();
    }

    @Test
    void 사용자_프로필조회_이름만조회() {
        UserResponse 사용자1 = RestAssured
                .given().log().all()
                .contentType(ContentType.JSON)
                .body(new UserRequest("추민영", "chuchu", "123", "chu@naver.com"))
                .when()
                .post("/users/infos")
                .then().log().all()
                .statusCode(200)
                .extract()
                .as(UserResponse.class);

        UserResponse 추민영 = RestAssured
                .given().log().all()
                .contentType(ContentType.JSON)
                .body(new UserProfileRequest(사용자1.id(), 사용자1.userName()))
                .when()
                .get("/users")
                .then().log().all()
                .statusCode(200)
                .extract()
                .as(UserResponse.class);

        assertThat(추민영.userName()).isNotNull();
    }

    @Test
    void 사용자정보_전체조회() {
        UserResponse 사용자1 = RestAssured
                .given().log().all()
                .contentType(ContentType.JSON)
                .body(new UserRequest("추민영", "chuchu", "123", "chu@naver.com"))
                .when()
                .post("/users/infos")
                .then().log().all()
                .statusCode(200)
                .extract()
                .as(UserResponse.class);

        UserResponse 사용자 = RestAssured
                .given().log().all()
                .contentType(ContentType.JSON)
                .queryParam("userId",사용자1.id())
                .when()
                .get("/users/profiles")
                .then().log().all()
                .statusCode(200)
                .extract()
                .as(UserResponse.class);

        assertThat(사용자.userId()).isEqualTo(사용자1.userId());
        assertThat(사용자.userName()).isEqualTo(사용자1.userName());
        assertThat(사용자.userPassword()).isEqualTo(사용자1.userPassword());
    }

    @Test
    void 사용자정보_수정() {
        String userName = "수정 전 이름";
        String updatedUserName = "수정 후 이름";

        UserResponse 수정전사용자 = RestAssured
                .given().log().all()
                .contentType(ContentType.JSON)
                .body(new UserRequest(userName, "chuchu", "123", "chu@naver.com"))
                .when()
                .post("/users/infos")
                .then().log().all()
                .statusCode(200)
                .extract()
                .as(UserResponse.class);

        UserResponse 수정후사용자 = RestAssured
                .given().log().all()
                .contentType(ContentType.JSON)
                .pathParam("userId", 수정전사용자.id())
                .body(new UserRequest(updatedUserName, "chuchu", "123", "chu@naver.com"))
                .when()
                .put("/users/{userId}")
                .then().log().all()
                .statusCode(200)
                .extract()
                .as(UserResponse.class);

        UserResponse 사용자 = RestAssured
                .given().log().all()
                .contentType(ContentType.JSON)
                .queryParam("userId", 수정후사용자.id())
                .when()
                .get("/users/profiles")
                .then().log().all()
                .statusCode(200)
                .extract()
                .as(UserResponse.class);

        assertThat(사용자.userName()).isEqualTo(updatedUserName);
    }

    @Test
    void 사용자정보_삭제() {
        UserResponse 삭제전사용자 = RestAssured
                .given().log().all()
                .contentType(ContentType.JSON)
                .body(new UserRequest("추민영", "chuchu", "123", "chu@naver.com"))
                .when()
                .post("/users/infos")
                .then().log().all()
                .statusCode(200)
                .extract()
                .as(UserResponse.class);

        RestAssured
                .given().log().all()
                .contentType(ContentType.JSON)
                .pathParam("userId", 삭제전사용자.id())
                .when()
                .delete("/users/{userId}")
                .then().log().all()
                .statusCode(200);

    }
}

😐 느낀점

API Spec을 작성하고나면 나머지 API 구현하는 일은 쉽다.
기본적인 API구현은 (CRUD) 잘 작성하기!

0개의 댓글