[横書きアイテム]そんなREST APIで大丈夫ですか?本格的なREST API-実装GETイベントの実装
31184 ワード
Get Event Testの作成
今回は,単一イベントを導入する論理を実現する.
ここで考えなければならないのは
@Test
public void get_event_success() throws Exception {
Event event = createEvent(0);
this.eventRepository.save(event);
mockMvc.perform(get("/api/events/{id}", event.getId()))
.andDo(print())
.andExpect(jsonPath("event").exists())
.andExpect(jsonPath("_links").exists());
}
@Test
public void get_event_not_found_event() throws Exception {
//Given
Integer wrongId = 10010;
mockMvc.perform(get("/api/events/{id}", wrongId))
.andDo(print())
.andExpect(status().isNotFound())
.andExpect(jsonPath("timestamp").exists())
.andExpect(jsonPath("status").exists())
.andExpect(jsonPath("error").exists())
.andExpect(jsonPath("message").exists());
}
サービスロジックの実装
Service Layerは、JPAでデータをロードし、nullでイベントに異常があるかどうかを確認します.
JPAからfindByにデータをインポートする場合は、Optional<>オブジェクトにデータを入れます.
このオプションオブジェクトのisEmpty()が真の場合、データが存在しないため、if文とthrow文で例外処理が行われます.
public Event read(Integer id){
Optional<Event> findEvent = this.eventRepository.findById(id);
if(findEvent.isEmpty())
throw new CustomException(HttpStatus.NOT_FOUND, "Event not found");
return findEvent.get();
}
CustomExceptionの実装とエラーレスポンスの変更
今、異常処理を行うときは、Custom Errorを使用して必要なエラーを投げ出します.
package com.carrykim.restapi.event.global.exception;
import lombok.Getter;
import org.springframework.http.HttpStatus;
@Getter
public class CustomException extends RuntimeException{
private HttpStatus httpStatus;
private String message;
public CustomException(HttpStatus httpStatus, String message){
this.httpStatus = httpStatus;
this.message = message;
}
}
package com.carrykim.restapi.event.global.exception;
import lombok.Builder;
import lombok.Getter;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
@Getter
public class ErrorResponse {
private final LocalDateTime timestamp = LocalDateTime.now();
private int status;
private List<String> message;
private String error;
public ErrorResponse(HttpStatus httpStatus , BindingResult bindingResult) {
this.status = httpStatus.value();
this.error = httpStatus.name();
this.message = bindingResult.getFieldErrors().stream()
.map(e -> {
String m = e.getField() + " : " + e.getDefaultMessage();
return m;
})
.collect(Collectors.toList());
}
public ErrorResponse(CustomException customException){
this.status = customException.getHttpStatus().value();
this.error = customException.getHttpStatus().name();
this.message = new ArrayList<>();
this.message.add(customException.getMessage());
}
}
EventExceptionHandlerの変更
EventExceptionHandlerが変更され、CustomExceptionが投げ出されるとエラーメッセージが表示されます.
package com.carrykim.restapi.event.global.exception;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.hateoas.MediaTypes;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
@RestControllerAdvice
public class EventExceptionHandler {
@ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseEntity validationErrorException(final MethodArgumentNotValidException e) {
return ResponseEntity
.status(HttpStatus.BAD_REQUEST)
.body(new ErrorResponse(HttpStatus.BAD_REQUEST,e.getBindingResult()));
}
@ExceptionHandler(CustomException.class)
public ResponseEntity customErrorException(final CustomException e){
return ResponseEntity
.status(e.getHttpStatus().value())
.body(new ErrorResponse(e));
}
}
Event Controlの変更
最後に、サービスレイヤーによって渡されたイベントオブジェクトをEventResourceオブジェクトに入れ、URIをマッピングして返します.
@GetMapping("/{id}")
public ResponseEntity read(@PathVariable Integer id){
Event event = this.eventService.read(id);
EventResource eventResource = new EventResource(event);
addLinks(eventResource);
return ResponseEntity.ok(eventResource);
}
テスト結果
Reference
この問題について([横書きアイテム]そんなREST APIで大丈夫ですか?本格的なREST API-実装GETイベントの実装), 我々は、より多くの情報をここで見つけました https://velog.io/@carrykim/사이드프로젝트-그저-그런-REST-API로-괜찮은가-진정한-REST-API-구현해보기-GET-Event-구현하기テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol