티스토리 뷰
DTO (Data Transfer Object)는 데이터 전송을 위한 객체로, 주로 계층 간 데이터 교환을 목적으로 사용됩니다.
예를 들어, 클라이언트에서 서버로 혹은 서비스 계층에서 프레젠테이션 계층으로 데이터를 전달할 때 사용됩니다.
ArticleDTO 생성
package com.example.demo._domain.blog.dto;
import com.example.demo._domain.blog.entity.Article;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
@NoArgsConstructor
@AllArgsConstructor
@Getter
// 즉, 주로 계층 간의 데이터 전송 목적으로 설계된다.
public class ArticleDTO {
private String title;
private String content;
// ArticleDTO -> Article 데이터 타입을 변환시키는 메서드
// Article 에 기본 생성자(@NoArgsConstructor) 선언 필요
public Article toEntity() {
return Article.builder()
.title(this.title)
.content(this.content)
.build();
}
}
서비스 계층은 애플리케이션에서 비즈니스 로직을 처리하는 중요한 역할을 합니다.
서비스 계층은 주로 컨트롤러와 데이터베이스 간의 중간 계층으로, 데이터를 조작하거나 처리하는 모든 비즈니스 규칙을 담당합니다.
BlogService 생성
package com.example.demo._domain.blog.service;
import org.springframework.stereotype.Service;
import com.example.demo._domain.blog.dto.ArticleDTO;
import com.example.demo._domain.blog.entity.Article;
import com.example.demo._domain.blog.repository.PostRepository;
import jakarta.transaction.Transactional;
import lombok.RequiredArgsConstructor;
@RequiredArgsConstructor
@Service // IoC(빈(객체)으로 등록)
public class BlogService {
// @Autowired // DI <-- 생략 가능하나 가독성 때문에 작성
// final - 초기화 반드시 보장X -> @RequiredArgsConstructor 필요
// final 사용 이유 -> 성능 상의 이점 있음
private final PostRepository postRepository;
@Transactional // 쓰기 지연 처리까지
public Article save(ArticleDTO dto) {
// 비즈니스 로직이 필요하다면 작성
return postRepository.save(dto.toEntity());
// postRepository는 JpaRepository를 상속받기 때문에 save() 사용 가능
}
}
@RequiredArgsConstructor 어노테이션은 PostRepository 를 매개변수로 받는 생성자를 자동 생성한다.
이 어노테이션을 사용할 경우 @Autowired 는 생략이 가능하나 가독성 때문에 함께 사용하기도 한다.
@Service 어노테이션은 해당 클래스를 스프링 컨테이너에 빈(Bean)으로 등록해주는 역할
즉, 스프링 컨테이너 또는 애플리케이션 컨텍스트에 빈으로 등록된다.
※ 추가 정보 ※
용어 정리
IoC(Inversion of Control)
객체의 생성과 의존성 관리의 책임을 개발자가 아닌 외부 컨테이너가 맡는 디자인 패턴
객체가 직접 자신을 생성하고 의존성을 관리하지만 IoC를 적용하면 이러한 작업을 스프링과 같은 프레임워크가 대신한다.
스프링 애플리케이션(Spring Application)
스프링 프레임워크를 기반으로 구축된 애플리케이션
다양한 비지니스 로직, 데이터 처리, 사용자 인터페이스 등을 포함한다.
여러 컴포넌트(빈)로 구성되어 있으며, 이는 스프링 컨테이너에 의해 관리된다.
애플리케이션 컨텍스트(ApplicationContext)
스프링 컨테이너의 구체적인 구현체 중 하나
스프링 애플리케이션에 대한 설정 정보 및 비지니스 로직을 담고 있는 컨테이너
BeanFactory의 기능을 확장한 인터페이스
스프링 컨테이너의 확장된 형태(스프링 컨테이너의 기능 포함)
=> 빈의 생명주기 관리, 의존성 주입 외에도 메시지 리소스 관리, 이벤트 전달 등을 담당한다.
AnnotationConfigApplicationContext, ClassPathXmlApplicationContext 와 같은 구체적인 구현체를 통해 스프링 애플리케이션을 초기화하고 설정한다.
스프링 컨테이너(Spring Container)
스프링 프레임워크가 애플리케이션을 관리하고 실행하는 핵심 부분
애플리케이션에서 사용할 객체들(빈)을 생성하고, 이 객체들 간의 의존성을 관리하며, 생명주기를 관리 하는 역할
IoC 원칙을 기반으로 동작하며 위의 역할을 개발자가 아닌 스프링 컨테이너에서 제어한다.
애플리케이션이 시작될 때 빈을 초기화하고 의존성 주입을 통해 서로 다른 컴포넌트를 연결한다.
+----------------------------------+
| Spring Application |
| |
| +--------------------------+ |
| | Application Context | |
| | | |
| | +------------------+ | |
| | | Spring Container | | |
| | | | | |
| | | +----------+ | | |
| | | | Beans | | | |
| | | +----------+ | | |
| | +------------------+ | |
| +--------------------------+ |
| |
+----------------------------------+
IoC 컨테이너의 작동 방식
1. 빈 정의: 스프링 애플리케이션에서 @Service, @Controller, @Component 등의 어노테이션을 사용하여 사용할 빈을 설정함. 이는 xml 파일이나 자바 클래스를 통해 이루어짐.
2. 컨테이너 초기화 및 빈 생성: 스프링 애플리케이션 시작 시 스프링 컨테이너가 정의된 빈을 스캔하고, 필요한 경우 인스턴스를 생성한다.
3. 의존성 주입: 각 빈은 다른 빈을 필요로 할 경우, 스프링 컨테이너는 필요한 의존성을 자동으로 주입한다. 예를 들어, UserController는 UserService를 필요로 하며, 스프링은 이를 자동으로 주입한다. 주입 방식에는 생성자 주입, setter 주입, 필드 주입 등이 있다.
4. 관리: 생성된 빈은 스프링 컨테이너가 관리하며 필요 시 생명 주기를 조정하고 스코프를 설정할 수 있다.
BlogApiController
사용자의 요청을 처리하고(URL 맵핑) 그 요청을 서비스 계층으로 전달하며, 결과를 다시 사용자에게 반환하는 역할을 합니다.
package com.example.demo._domain.blog.controller;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import com.example.demo._domain.blog.dto.ArticleDTO;
import com.example.demo._domain.blog.entity.Article;
import com.example.demo._domain.blog.service.BlogService;
import lombok.RequiredArgsConstructor;
@RequiredArgsConstructor
@RestController // @controller + @responsebody
public class BlogApiController {
private final BlogService blogService;
// URL 매핑(주소 설계) - http://localhost:8080/api/articles
@PostMapping("/api/articles")
public ResponseEntity<Article> addArticle(@RequestBody ArticleDTO dto) {
// 1. 인증 검사
// 2. 유효성 검사
Article savedArticle = blogService.save(dto);
return ResponseEntity.status(HttpStatus.CREATED).body(savedArticle);
// http의 body에 savedArticle 넣음
}
}
postman을 사용해서
POST 방식으로 send하면
data를 insert 할 수 있습니다.
h2-console에서 insert 된 data 값을 확인할 수 있습니다.
※ 기억해야 할 응답 코드 ※
200 OK: 요청이 성공적으로 처리되었습니다.
201 Created: 요청이 성공적으로 처리되었고, 새로운 리소스가 생성되었습니다.
302 Found: 요청한 리소스가 임시적으로 다른 URL로 리다이렉트됩니다.
400 Bad Request: 클라이언트의 요청이 잘못되었거나 서버가 요청을 이해할 수 없습니다.
401 Unauthorized: 인증이 필요하지만 클라이언트가 인증되지 않았습니다.
403 Forbidden: 클라이언트가 요청한 리소스에 접근할 권한이 없습니다.
404 Not Found: 요청한 리소스를 찾을 수 없습니다.
500 Internal Server Error: 서버에서 오류가 발생하여 요청을 처리할 수 없습니다.
'JPA' 카테고리의 다른 글
글 상세보기(조회) API 구현 (0) | 2024.10.02 |
---|---|
글 목록 조회 API 만들기 (0) | 2024.10.02 |
블로그 레포지토리 만들기 (0) | 2024.10.02 |
블로그 엔티티 만들기 (0) | 2024.10.01 |
블로그 프로젝트 만들기 (4) | 2024.10.01 |