REST API 를 통해 게시물을 CRUD -
Create(생성), Read(읽기), Update(갱신), Delete(삭제) 적용
패키지 구조
application.properties
spring.datasource.dbcp2.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/myblog?userSSL=false&serverTimezone=Asia/Seoul&characterEncoding=UTF-8
spring.datasource.username = root
spring.datasource.password = root
# hibernate properties
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5InnoDBDialect
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto= update
Creating JPA Entity
JPA 를 통해 데이터베이스 테이블 생성
@Data // getter setter requiredArgsConstructor toString
@NoArgsConstructor
@AllArgsConstructor
@Entity
@Table(name="posts", uniqueConstraints = {@UniqueConstraint(columnNames= {"title"})})
public class Post
{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name="title", nullable=false)
private String title;
@Column(name="description", nullable=false)
private String description;
@Column(name="content", nullable=false)
private String content;
}
MySQL posts 테이블 생성
Creating JPA Repository
//We don't need to @Repository annotation to this interface
//because the JpaRepository interface has an implementation
//SimpleJpaRepository internally annotated with @Repository annotation and @Transactional
public interface PostRepository extends JpaRepository<Post, Long>
{
}
Creating Custom Exception
사용자 정의 예외 처리
/* This is cause Spring boot to respond with the specified HTTP status code
* whenever this exception is thrown from your controller. */
@ResponseStatus(value= HttpStatus.NOT_FOUND)
@Getter
public class ResourceNotFoundException extends RuntimeException
{
private String resourceName;
private String fieldName;
private long fieldValue;
public ResourceNotFoundException(String resourceName, String fieldName, long fieldValue) {
super(String.format("%s not found with %s : '%s'", resourceName, fieldName, fieldValue));
this.resourceName = resourceName;
this.fieldName = fieldName;
this.fieldValue = fieldValue;
}
}
HTTP status code의 NOT_FOUND 에러 발생시 ResourceNotFoundException 처리, 해당 클래스 호출
2022-06-27 10:54:14.299 WARN 2232 --- [nio-8080-exec-4] .w.s.m.a.ResponseStatusExceptionResolver : Resolved [com.springboot.blog.exception.ResourceNotFoundException: Post not found with id : '6']
Creating DTO Class
클라이언트에 데이터를 보여주기 위함.
@Data
public class PostDto
{
private long id;
private String title;
private String description;
private String content;
}
Service interface
public interface PostService
{
public PostDto createPost(PostDto postDto);
public List<PostDto>getAllPosts();
public PostDto getPostById(Long id);
public PostDto updatePost(PostDto postDto, Long id);
public void deletePostById(Long id);
}
Service
@Service
public class PostServiceImpl implements PostService
{
private PostRepository postRepository;
// inject
public PostServiceImpl(PostRepository postRepository) {
this.postRepository = postRepository;
}
@Override
public PostDto createPost(PostDto postDto) {
// convert DTO to entity
Post post = mapToEntity(postDto);
Post newPost =postRepository.save(post);
// convert entity to DTO
PostDto postResponse = mapToDTO(newPost);
return postResponse;
}
@Override
public List<PostDto> getAllPosts() {
List<Post> posts= postRepository.findAll();
return posts.stream().map(post -> mapToDTO(post)).collect(Collectors.toList());
}
// convert DTO to entity
private Post mapToEntity(PostDto postDto)
{
Post post = new Post();
post.setTitle(postDto.getTitle());
post.setDescription(postDto.getDescription());
post.setContent(postDto.getContent());
return post;
}
// convert entity to DTO
private PostDto mapToDTO(Post post)
{
PostDto postdto = new PostDto();
postdto.setId(post.getId());
postdto.setTitle(post.getTitle());
postdto.setDescription(post.getDescription());
postdto.setContent(post.getContent());
return postdto;
}
@Override
public PostDto getPostById(Long id) {
Post post = postRepository.findById(id).orElseThrow(()->new ResourceNotFoundException("Post", "id", id));
return mapToDTO(post);
}
@Override
public PostDto updatePost(PostDto postDto, Long id) {
Post post = postRepository.findById(id).orElseThrow(()->new ResourceNotFoundException("Post", "id", id));
post.setTitle(postDto.getTitle());
post.setDescription(postDto.getDescription());
post.setContent(postDto.getContent());
return mapToDTO(postRepository.save(post));
}
@Override
public void deletePostById(Long id) {
Post post = postRepository.findById(id).orElseThrow(()->new ResourceNotFoundException("Post", "id", id));
postRepository.delete(post);
}
}
Controller
@RestController
@RequestMapping("/api/posts")
public class PostController
{
private PostService postService;
// if you are configuring a class as a spring bean and it has only one constructor,
// then we can omit @Autowired annotation
public PostController(PostService postService) {
this.postService = postService;
}
@GetMapping
public List<PostDto> getAllPosts() {
return postService.getAllPosts();
}
@PostMapping
public ResponseEntity<PostDto> createPost(@RequestBody PostDto postDto){
return new ResponseEntity<>(postService.createPost(postDto),HttpStatus.CREATED);
}
// get post by id
@GetMapping("/{id}")
public ResponseEntity<PostDto> getPostById(@PathVariable(name= "id") long id){
return ResponseEntity.ok(postService.getPostById(id));
}
// update post by id rest api
@PutMapping("/{id}")
public ResponseEntity<PostDto> updatePost(@RequestBody PostDto postDto, @PathVariable(name="id") long id){
PostDto postResponse = postService.updatePost(postDto, id);
return new ResponseEntity<>(postResponse,HttpStatus.OK);
}
// delete post by id rest api
@DeleteMapping("/{id}")
public ResponseEntity<String> deletePost(@PathVariable Long id)
{
postService.deletePostById(id);
return new ResponseEntity<>("삭제 완료",HttpStatus.OK);
}
}
Create
@PostMapping
public ResponseEntity<PostDto> createPost(@RequestBody PostDto postDto){
return new ResponseEntity<>(postService.createPost(postDto),HttpStatus.CREATED);
}
Read
All Read
@GetMapping
public List<PostDto> getAllPosts() {
return postService.getAllPosts();
}
post by id
// get post by id
@GetMapping("/{id}")
public ResponseEntity<PostDto> getPostById(@PathVariable(name= "id") long id){
return ResponseEntity.ok(postService.getPostById(id));
}
Update
// update post by id rest api
@PutMapping("/{id}")
public ResponseEntity<PostDto> updatePost(@RequestBody PostDto postDto, @PathVariable(name="id") long id){
PostDto postResponse = postService.updatePost(postDto, id);
return new ResponseEntity<>(postResponse,HttpStatus.OK);
}
Delete
// delete post by id rest api
@DeleteMapping("/{id}")
public ResponseEntity<String> deletePost(@PathVariable Long id)
{
postService.deletePostById(id);
return new ResponseEntity<>("삭제 완료",HttpStatus.OK);
}
해당 아이디가 없을 때
'Back-end > Spring Boot + REST API' 카테고리의 다른 글
Spring boot - blog application (REST API) : Comment (0) | 2022.07.03 |
---|---|
Spring boot - blog application (REST API) : Pagination and Sorting Support (0) | 2022.06.30 |
Spring boot - blog application (REST API) (0) | 2022.06.28 |
Spring Boot 컨트롤러에서 데이터 받는 방법(@RequestBody, @RequestParam, @PathVariable) (0) | 2022.06.27 |
SpringBoot 개념정리 (0) | 2022.06.22 |
댓글