CRUD를 구현할때 R(Read)을 제외한 API들의 Response 값을 공통으로 포맷하여 프론트에 리턴해주는 기능을 개발했던 과정을 정리해 보겠습니다.
1. Response 값을 공통으로 포맷하여 리턴해줄 때 얻게 되는 장점
- GET 요청 API를 제외한 모든 API들의 Response 값이 동일하기 때문에 백엔드와 프론트 둘 다 구조적인 측면에서 좋습니다.
- 프론트 입장에서 공통 Response 값을 보고 편리하게 응답 상태를 구분할 수 있습니다.
2. Response 값 CASE 정리
CASE 1. 정상 (status = success)
ex)
CASE 2. 실패 (status = fail)
ex)
CASE 3. 에러 (status = error)
3. 공통 Response값에 사용될 ApiResult Class 및 공통 에러 데이터를 담을 ApiExceptionEntity Class 생성
3-1. ApiResult.java
package com.example.login.common.api;
import com.example.login.common.error.ApiExceptionEntity;
import lombok.*;
@Getter
@NoArgsConstructor
@ToString
public class ApiResult{
private String status;
private String message;
private ApiExceptionEntity exception;
@Builder
public ApiResult(String status, String message, ApiExceptionEntity exception) {
this.status = status;
this.message = message;
this.exception = exception;
}
}
3-2. ApiExceptionEntity.java
package com.example.login.common.error;
import lombok.Builder;
import lombok.Getter;
import lombok.ToString;
import org.springframework.http.HttpStatus;
@Getter
@ToString
public class ApiExceptionEntity {
private String errorCode;
private String errorMessage;
@Builder
public ApiExceptionEntity(HttpStatus status, String errorCode, String errorMessage){
this.errorCode = errorCode;
this.errorMessage = errorMessage;
}
}
4. CASE 1 & CASE 2 구현
(※ 에러 처리(CASE 3) 구현은 다음 글에서 정리해 보도록 하겠습니다. ※)
4-1. UserController.java
@ApiOperation(value="로그인", notes="Status Fail Case"
+ "\n 1. 아이디가 틀렸을 때 -> message: idFail"
+ "\n 2. 비밀번호가 틀렸을 때 -> message: pwFail")
@PostMapping("/login")
public ApiResult login(@RequestBody LoginRequestDto loginRequestDto, HttpServletRequest request, HttpServletResponse response) {
return service.userLoginCheck(loginRequestDto, service.selectUser(loginRequestDto.getId()), response, request);
}
4-2. UserService.java
@Override
public ApiResult userLoginCheck(LoginRequestDto loginRequestDto, UserVO userVo, HttpServletResponse response, HttpServletRequest request) {
if(userVo != null) {
BCryptPasswordEncoder encode = new BCryptPasswordEncoder();
if(encode.matches(loginRequestDto.getPassword(),userVo.getPassword())) {
request.getSession().setAttribute("login",userVo);
//자동로그인을 체크했을시에 실행
if(loginRequestDto.isAutoLogin()) {
//3개월뒤의 초
long second = 60 * 60 * 24 * 90;
//쿠키생성
Cookie cookie = new Cookie("loginCookie", request.getSession().getId());
cookie.setPath("/");
cookie.setMaxAge((int)second);
response.addCookie(cookie);
//3개월뒤의 밀리초를 날짜로 변환
long millis = System.currentTimeMillis() + (second * 1000);
Date limitDate = new Date(millis);
//DB에 세션아이디,쿠키만료날짜,회원 아이디 전달
userAutoLogin(request.getSession().getId(), limitDate, loginRequestDto.getId());
}
apiResult = ApiResult.builder()
.status("success")
.message("loginSuccess")
.build();
}else {
apiResult = ApiResult.builder()
.status("fail")
.message("pwFail")
.build();
}
}else {
apiResult = ApiResult.builder()
.status("fail")
.message("idFail")
.build();
}
return apiResult;
}
5. Test 코드 작성
UserControllerTest.java
@Test
void testLogin() {
try {
UserVO userVo = new UserVO();
userVo.setId("testId");
userVo.setPassword("testPw");
String jsonData = new Gson().toJson(userVo);
mvc.perform(post("/api/user/login")
.contentType(MediaType.APPLICATION_JSON)
.content(jsonData))
.andExpect(status().isOk())
.andExpect(jsonPath("$.status", "success").exists());
} catch (Exception e) {
e.printStackTrace();
}
}
'Spring Framework' 카테고리의 다른 글
[Spring Boot] REST-API 공통 에러(Exception) 처리 개발 과정 (0) | 2023.03.17 |
---|---|
Spring Boot 프로젝트에서 Mybatis로 Mysql 데이터베이스(DB) 연동하는법 (2) | 2021.10.05 |
(Spring,JSP) JSP에서 날짜 값을 fmt태그를 사용해 포맷하는법 (0) | 2021.09.24 |
(Spring)Postman를 사용해서 Spring으로 구축한 REST API 서버가 정상작동하는지 테스트 하는 방법 (0) | 2021.09.20 |
Spring Boot에서 JSP 연동(사용)하는 방법 (0) | 2021.09.19 |