spring boot #11

·2022년 5월 1일
0

spring

목록 보기
12/22

기존 RestAPI 구현에 서비스 계층을 추가하기.

🤔 Service Layer

service는 controller와 repository 사이에 있는 계층으로 업무의 순서를 총괄한다.

기존의 ArticleApiController.java에서 ArticleRepository로 연결되는 부분을 ArticleService의 객체로의 연결로 변경해준다.

@RestController
public class ArticleApiController {

	//DI. 생성 객체를 가져와 연결
    @Autowired
    private ArticleService articleService;


    //get
    @GetMapping("/api/articles")
    public List<Article> index(){
        return articleService.index();
    }
    @GetMapping("/api/articles/{id}")
    public Article show(@PathVariable Long id){
        return articleService.show(id);
    }


    //post
    @PostMapping("/api/articles")
    public ResponseEntity<Article> crete(@RequestBody ArticleForm dto){
        Article created = articleService.create(dto);
        return (created != null) ?
                ResponseEntity.status(HttpStatus.OK).body(created) :
                ResponseEntity.status(HttpStatus.BAD_REQUEST).build();
    }


    //patch
    @PatchMapping("/api/articles/{id}")
    public ResponseEntity<Article> update(@PathVariable Long id, @RequestBody ArticleForm dto){

        Article updated = articleService.update(id,dto);
        return (updated != null)?
                ResponseEntity.status(HttpStatus.OK).body(updated):
                ResponseEntity.status(HttpStatus.BAD_REQUEST).build();

    }


    //delete
    @DeleteMapping("/api/articles/{id}")
    public ResponseEntity<Article> delete(@PathVariable Long id){
        Article deleted = articleService.delete(id);
        return (deleted!= null)?
            ResponseEntity.status(HttpStatus.OK).build():
            ResponseEntity.status(HttpStatus.BAD_REQUEST).build();
    }
}

@Service

서비스 선언. 서비스 객체를 스프링 부트에 생성해주는 어노테이션.

@Service
public class ArticleService {

    @Autowired
    private ArticleRepository articleRepository;

    public List<Article> index() {
        return articleRepository.findAll();
    }

    public Article show(Long id) {
        return articleRepository.findById(id).orElse(null);
    }

    public Article create(ArticleForm dto) {
        Article article = dto.toEntity();
        if(article.getId() != null){
            return null;
        }
        return articleRepository.save(article);
    }

    public Article update(Long id, ArticleForm dto) {
        Article article = dto.toEntity();
        Article target = articleRepository.findById(id).orElse(null);

        if(target == null || id != dto.toEntity().getId()){
            return null;
        }
        target.patch(article);
        return articleRepository.save(target);
    }

    public Article delete(Long id) {
        Article target= articleRepository.findById(id).orElse(null);

        if(target ==null){
            return null;
        }
        articleRepository.delete(target);
        return target;
    }
}

🤔 transaction

  • 트렌젝션 : 한번에 성공해야 하는 일련의 과정

  • 서비스가 트렌젝션을 관리한다.

  • 트렌젝션을 연습해보기 위해서 ResponseEntity<List< Article>>을 통해 여러 데이터를 한번에 요청 받는다.
    (예를 들어, id=1/식당 입장 - id=2/메뉴 고민 - id=3 주문완료 )

//ArticleApiController.java

  @PostMapping("/api/transaction-test")
    public ResponseEntity<List<Article>> transactionTest(@RequestBody List<ArticleForm> dtos){
        List<Article> createdList = articleService.createArticles(dtos);
        return (createdList != null)?
                ResponseEntity.status(HttpStatus.OK).body(createdList):
                ResponseEntity.status(HttpStatus.BAD_REQUEST).build();
    }

@Transactional

해당 메소드를 트렌젝션으로 묶어줌.

Roll back

트렌젝션 메소드는 중간에 과정이 실패하면 초기단계로 돌아오는 롤백 기능이 있다.

//ArticleService.java

 @Transactional
    public List<Article> createArticles(List<ArticleForm> dtos) {

		 //dto묶음을 entity묶음으로 변환
        List<Article> articleList = dtos.stream()
                .map(dto -> dto.toEntity())
                .collect(Collectors.toList());

		 //entity묶음을 DB로 저장
        articleList.stream()
                .forEach(article -> articleRepository.save(article));

		//강제 예외 발생
        articleRepository.findById(-1L).orElseThrow(
                () ->  new IllegalArgumentException("fail..")
        );

        return articleList;
    }

위의 코드를 for문으로 작성한다면..

id값을 음수로 줘서 일부러 에러를 발생시켰다.
트렌젝션으로 묶어주었기 때문에 롤백 기능 > 에러가 발생했을때 초기단계로 돌아간다.

500 서버 내부 에러

🤔 정리

기존 RestAPI 구현에 Service 계층을 추가해줌으로..

Controller는 client한테 "요청받기", "응답처리"만 실행하고,

Service가 "업무처리"와 "업무흐름(트렌젝션)관리" 또한 "업무과정 실패에 대한 처리(롤백)"을 실행한다.

0개의 댓글

관련 채용 정보

Powered by GraphCDN, the GraphQL CDN