# HTTP와 RestController
## 미션
Article 데이터 CRUD를 위한, REST API를 만드시오.
![홍팍-스프링-부트-입문-REST-API-미션](http://drive.google.com/thumbnail?export=view&sz=w960&id=1e55X1bphbY5iniXAAM4OeSweWGasOqcP)
## 03:28 헬로 RestAPI - @RestController
#### ../api/FirstApiController
```
package com.example.firstproject.api;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class FirstApiController {
@GetMapping("/api/hello")
public String hello() {
return "hello world!";
}
}
```
## 06:43 RestAPI GET 구현 - @GetMapping, @Autowired, DI
#### ../api/ArticleApiController
```
package com.example.firstproject.api;
import com.example.firstproject.entity.Article;
import com.example.firstproject.repository.ArticleRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@RestController
public class ArticleApiController {
@Autowired
private ArticleRepository articleRepository;
// GET
@GetMapping("/api/articles")
public List<Article> index() {
return articleRepository.findAll();
}
@GetMapping("/api/articles/{id}")
public Article show(@PathVariable Long id) {
return articleRepository.findById(id).orElse(null);
}
// POST
// PATCH
// DELETE
}
```
## 11:14 RestAPI POST 구현 - @PostMapping, @RequestBody
#### .../api/ArticleApiController
```
...
@RestController
public class ArticleApiController {
...
// POST
@PostMapping("/api/articles")
public Article create(@RequestBody ArticleForm dto) {
Article article = dto.toEntity();
return articleRepository.save(article);
}
// PATCH
// DELETE
}
```
## 14:46 RestAPI PATCH 구현
#### ../api/ArticleApiController
```
...
@Slf4j
@RestController
public class ArticleApiController {
...
// PATCH
@PatchMapping("/api/articles/{id}")
public ResponseEntity<Article> update(@PathVariable Long id,
@RequestBody ArticleForm dto) {
// 1: DTO -> 엔티티
Article article = dto.toEntity();
log.info("id: {}, article: {}", id, article.toString());
// 2: 타겟 조회
Article target = articleRepository.findById(id).orElse(null);
// 3: 잘못된 요청 처리
if (target == null || id != article.getId()) {
// 400, 잘못된 요청 응답!
log.info("잘못된 요청! id: {}, article: {}", id, article.toString());
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(null);
}
// 4: 업데이트 및 정상 응답(200)
target.patch(article);
Article updated = articleRepository.save(target);
return ResponseEntity.status(HttpStatus.OK).body(updated);
}
// DELETE
}
```
#### ../entity/Article
```
package com.example.firstproject.entity;
...
public class Article {
...
public void patch(Article article) {
if (article.title != null)
this.title = article.title;
if (article.content != null)
this.content = article.content;
}
}
```
## 23:58 RestAPI DELETE 구현
#### ../api/ArticleApiController
```
...
@Slf4j
@RestController
public class ArticleApiController {
...
// DELETE
@DeleteMapping("/api/articles/{id}")
public ResponseEntity<Article> delete(@PathVariable Long id) {
// 대상 찾기
Article target = articleRepository.findById(id).orElse(null);
// 잘못된 요청 처리
if (target == null) {
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(null);
}
// 대상 삭제
articleRepository.delete(target);
return ResponseEntity.status(HttpStatus.OK).build();
}
}
```
## 🔥 구글링 훈련하기
- @RestController
- @RequestBody
- JSON이란
- Spring ResponseEntity
- @PatchMapping
- @DeleteMapping
- 도메인 모델 패턴
- 트랜잭션 스크립트 패턴