- ์คํ๋ง MVC์์ REST ์๋ํฌ์ธํธ ์ ์ํ๊ธฐ
- ํ์ดํผ๋งํฌ REST ๋ฆฌ์์ค ํ์ฑํํ๊ธฐ
- ๋ ํฌ์งํ ๋ฆฌ ๊ธฐ๋ฐ์ REST ์๋ํฌ์ธํธ ์๋ํ
SPA(Single-Page Application)์ด ๋ฑ์ฅํ๋ฉด์ ์๋ฒ์์๋ ์ฌ๋ฌ๊ฐ์ ๋ทฐ๋ฅผ ๋ฐํํด์ฃผ๋ ๊ฒ์ด ์๋ ๋ฐ์ดํฐ๋ง ์ ๊ณตํ๋ฉฐ, ์ด๋ฅผ ํด๋ผ์ด์ธํธ ๋จ์์ ์ฒ๋ฆฌํ๊ฒ ๋๋ค. SPA์์๋ ํ๋ฆฌ์ ํ ์ด์ ๊ณ์ธต(๋ทฐ)์ด ์๋ ๊ณ์ธต๊ณผ๋ ๊ฑฐ์ ๋ ๋ฆฝ์ ์ด๋ฏ๋ก ๋ค๋ฅธ ์ ํ๋ฆฌ์ผ์ด์ (๋ชจ๋ฐ์ผ)์์๋ ์ฌ์ฉ์ด ๊ฐ๋ฅํ๋ค. ํ์ง๋ง, ํญ์ SPA๊ฐ ์ ๋ต์ ์๋๋ฉฐ ๋จ์ํ๊ฒ ์ ๋ณด๋ง ๋ณด์ฌ์ฃผ๋ ํ์ด์ง์ผ ๊ฒฝ์ฐ MPA(Multi-Page Application)์ด ์ข์ ์ ์๋ค.
์ต๊ทค๋ฌ ํน์ ๋ฆฌ์กํธ์ ๊ฐ์ ํ๋ก ํธ์ ํ๋ ์์ํฌ ํน์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์์๋ SPA๋ฅผ ๊ตฌ์ถํ๋ค๋ฉด, ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ๊ฑฐ๋ ๊ฐ์ ธ์ค๊ธฐ ์ํด์ REST API๋ฅผ ์์ฑํด์ผ ํ๋ค. 2์ฅ์์ ๋ณด์๋ @GetMapping ํน์ @PostMapping ๋ฑ ์ฌ๋ฌ๊ฐ์ง HTTP ์์ฒญ-์ฒ๋ฆฌ ์ ๋ ธํ ์ด์ ๋ค์ REST API์์๋ ์ฌ์ฉ๋๋ค.
@RestController ์ ๋ ธํ ์ด์ ์ @Controller์ @Service์ ๊ฐ์ ์คํ ๋ ์ค ํ์ ์ ์ ๋ ธํ ์ด์ ์ผ๋ก ์ปดํฌ๋ํธ ์ค์บ์ ์ํด ๋ฐ๊ฒฌ๋์ด์ง ์ ์๋ค. ๋, ์ปจํธ๋กค๋ฌ์ ๋ชจ๋ HTTP ์์ฒญ ์ฒ๋ฆฌ ๋ฉ์๋์ ๋ฐํ๊ฐ์ด Body์ ๋ด๊ธด๋ค๋ ๊ฒ์ ์คํ๋ง์ ์๋ ค์ค๋ค. ์ฆ, ๋ฐํ๊ฐ์ด ๋ทฐ๋ก ์ด์ด์ง๋ ๊ฒ์ด ์๋ HTTP ์๋ต์ผ๋ก ๋ธ๋ผ์ฐ์ ์ ์ ๋ฌ๋์ด ๋ํ๋๋ค.
๊ผญ ์ด ์ ๋ ธํ ์ด์ ์ ์ฌ์ฉํด์ผํ๋ ๊ฒ์ ์๋๋ค. ๊ธฐ์กด @Controller ์ ๋ ธํ ์ด์ ์ ์ฌ์ฉํด์๋ ๋๊ฐ์ ๊ธฐ๋ฅ์ ๋ง๋ค ์ ์๋๋ฐ ์ด๋๋ @ResonseBody ์ ๋ ธํ ์ด์ ์ ์ฌ์ฉํด์ผ ํ๋ค. @RestController์ ์ฝ๋๋ฅผ ์ดํด๋ณด๋ฉด @Controller์ @ResonseBody ์ ๋ ธํ ์ด์ ์ด ๋ด๋ถ์์ ์ง์ ๋์ด ์๋ ๊ฒ์ ๋ณผ ์ ์๋ค.
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Controller
@ResponseBody
public @interface RestController {
/**
* The value may indicate a suggestion for a logical component name,
* to be turned into a Spring bean in case of an autodetected component.
* @return the suggested component name, if any (or empty String otherwise)
* @since 4.0.1
*/
@AliasFor(annotation = Controller.class)
String value() default "";
}
์ด์ธ์๋ ResponseEntity ๊ฐ์ฒด๋ฅผ ๋ฐํํ๋ ๋ฐฉ๋ฒ์ด ์กด์ฌํ๊ธฐ๋ ํ๋ค.
๋ธ๋ผ์ฐ์ ์์๋ ๋ณด์ ๋ชฉ์ ์ผ๋ก ๋ค๋ฅธ ๋๋ฉ์ธ์ ์์ฒญ์ ๋ํ ์๋ต์ ์ฐจ๋จํ๊ณ ์๋ค(SOP(Same-Origin Poicy)). ํ์ง๋ง CORS(Cross-Origin Resource Sharing)๋ฅผ ํตํด ์์ธ์ ์ธ ์ํฉ์ ๋ง๋ค ์ ์๋ค. ์์ธํ ๋ด์ฉ์ ๋งํฌ๋ฅผ ํ๊ณ ๋ค์ด๊ฐ ๋ณด๊ธฐ๋ฅผ ๋ฐ๋๋ค. ์คํ๋ง์์๋ @CrossOrigin ์ ๋ ธํ ์ด์ ์ ํตํด ์ฝ๊ฒ CORS๋ฅผ ์ ์ฉํ ์ ์๋ค.
๋ฐ์ดํฐ ๋ณ๊ฒฝ์ ์ํด HTTP ๋ฉ์๋๋ PUT๊ณผ PATCH๊ฐ ์กด์ฌํ๋ค. ๋ฌด์์ด ๋ค๋ฅธ์ ์ผ๊น?
PUT์ ๋ฐ์ดํฐ๋ฅผ ๋ณ๊ฒฝํ๋ ๋ฐ ์ฌ์ฉํ๊ธด ํ์ง๋ง, ์ค์ ๋ก๋ GET๊ณผ ๋ฐ๋์ ์๋ฏธ๋ฅผ ๊ฐ๋๋ค. GET์ ์๋ฒ์์ ํด๋ผ์ด์ธํธ๋ก ๋ฐ์ดํฐ๋ฅผ ์ ์กํ๋ ๋ฐ๋ฉด, PUT ์์ฒญ์ ํด๋ผ์ด์ธํธ์์ ์๋ฒ๋ก ๋ฐ์ดํฐ๋ฅผ ์ ์กํ๋ค.
์ด๋ฌํ ๊ด์ ์์ PUT์ ๋ฐ์ดํฐ ์ ์ฒด๋ฅผ ๊ต์ฒดํ๋ ๊ฒ์ด๋ฉฐ, PATCH์ ๋ชฉ์ ์ ๋ฐ์ดํฐ์ ์ผ๋ถ๋ถ๋ง ๋ณ๊ฒฝํ๋ ๊ฒ์ด๋ค. ๋ง์ฝ ์ผ๋ถ๋ถ์ ๋ณ๊ฒฝํ๋๋ฐ PUT ๋ฉ์๋๋ฅผ ์ฌ์ฉํ๋ค๋ฉด ๋ค๋ฅธ ์์ฑ๋ค์ null๋ก ๋ณ๊ฒฝ์ด ๋๋ค.
PATCH๋ฅผ ์ฌ์ฉํ ๋๋ ๋๊ฐ์ง ์ ์ฝ์ด ์กด์ฌํ๋ค.
- ํน์ ํ๋์ ๋ฐ์ดํฐ๋ฅผ ๋ณ๊ฒฝํ์ง ์๋๋ค๋ ๊ฒ์ผ๋ก null์ ์ฌ์ฉํ๋ค๋ฉด, ํด๋ผ์ด์ธํธ์์๋ ์ด๋ฅผ ๋ํ๋ผ ์ ์๋ ๋ฐฉ๋ฒ์ด ํ์ํ๋ค.
- ์ปฌ๋ ์ ์ ์ ์ฅ๋ ํญ๋ชฉ์ ์ญ์ ํน์ ์ถ๊ฐํ ๋ฐฉ๋ฒ์ ์๋ค. ์ด๋ฅผ ํ๋ ค๋ฉด ์ ์ฒด๋ฅผ ์ ์กํด์ผ ํ๋ค.
RESTํ API๋ฅผ ๋ง๋ค๊ธฐ ์ํด์ **HATEOAS(**Hypermedia As The Engine Of Application State)๋ฅผ ๋ง์กฑํด์ผ ํ๋ค. ์ด๋ API๋ก๋ถํฐ ๋ฐํ๋๋ ๋ฆฌ์์ค์ ํด๋นํ์ฌ ๊ด๋ จ๋ ํ์ดํผ๋งํฌ๋ค์ด ํฌํจ๋์ด์ผ ํ๋ค.
HAL์ HATEOAS์ format์ค ํ๋๋ก JSON ๋๋ XML ์๋ต์ ํ์ดํผ๋งํฌ๋ฅผ ํฌํจ์ํฌ ๋ ์ฃผ๋ก ์ฌ์ฉ๋๋ค. ์๋ต์ ๋ชจ์ต์ ๋ค์๊ณผ ๊ฐ๋ค.
{
"_embedded" :
{
"tacoResourceList" :
[
{
"name": "Veg-Out",
"createdAt": "~~",
"ingredients":
[
{
"name": "Flour Tortilla",
"type": "WRAP",
"_links" :
{
"self" : {"href": "http://localhost:8080/ingredients/FLTO"}
}
}
...
]
}
]
},
"_links": {
"recents": {
"href": "http://localhost:8080/design/recent"
}
}
}
์ด์ ๊ฐ์ด ์ ๋ฌํ๋ ค๋ ๋ฐ์ดํฐ ์์ _links
๋ผ๋ ์์ฑ์ ํฌํจํ๊ฒ ๋๋ค. ์ด๋ ๋ฐ์ดํฐ๋ฅผ ๋ฐ๋ ํด๋ผ์ด์ธํธ ์ธก์์ API๋ฅผ ์ํ ํ ์ ์๋ ํ์ดํผ๋งํฌ๋ฅผ ํฌํจํ๊ณ ์๋ค.
์ด๋ฅผ ์ฌ์ฉํ๊ธฐ ์ํด์ ์ฐ๋ฆฌ๋ spring-boot-stater-hatedoas
์์กด์ฑ์ ์ถ๊ฐํ๊ธฐ๋ง ํ๋ฉด๋๋ค.
์ฑ
์์ ํ์ดํผ๋งํฌ ๋ฆฌ์์ค๋ฅผ ๋ํ๋ด๋ ํ์
์ผ๋ก Resource
์ Resources
๋ฅผ ์ค๋ช
ํ๊ณ ์๋ค. ์ด๋ EntityModel
๊ณผ CollectionModel
์ผ๋ก ๋ณ๊ฒฝ๋์๊ธฐ์ ๋ณ๊ฒฝ๋ ์ด๋ฆ์ผ๋ก ์ฌ์ฉํ ๊ฒ์ด๋ค(์์ธํ ๋ด์ฉ์ ๋งํฌ ์ฐธ๊ณ ). EntityModel
ํ์
์ ๋จ์ผ ๋ฆฌ์์ค๋ฅผ ๊ทธ๋ฆฌ๊ณ CollectionModel
ํ์
์ ๋ฆฌ์์ค ์ปฌ๋ ์
์ ๋ํ๋ด๋ฉฐ, ์ด ๋์ ๋ค๋ฅธ ๋ฆฌ์์ค๋ฅผ ๋งํฌํ ์ ์๋ค.
์ด๋ฅผ ํตํด์ ์ฐ๋ฆฌ๋ ๋ค์๊ณผ ๊ฐ์ด ๋งํฌ๋ฅผ ์ถ๊ฐ ํ ์ ์๋ค.
@GetMapping("/recent")
public CollectionModel<EntityModel<Taco>> recentTacos() {
PageRequest page = PageRequest.of(0, 12, Sort.by("createdAt").descending());
List<Taco> tacos = tacoRepo.findAll(page).getContent();
CollectionModel<EntityModel<Taco>> recentResources = CollectionModel.wrap(tacos);
recentResources.add(Link.of("http://localhost:8080/design/recent","recents"));
return recentResources;
}
ํ๋ํ๋ ํ๋์ฝ๋ฉ์ผ๋ก ๋งํฌ๋ฅผ ์ถ๊ฐํ๋ค๋ฉด ๊ต์ฅํ ์ข์ง ์์ ๋ฐฉ๋ฒ์ด๋ค. ์คํ๋ง HATEOAS์์๋ ๋งํฌ ๋น๋๋ฅผ ์ ๊ณตํ์ฌ URL์ ํ๋์ฝ๋ฉํ์ง ์๋ ๋ฐฉ๋ฒ์ ์ ๊ณตํ๋ค. WebMvcLinkBuilder
์ด ๋ฐ๋ก HATEOAS ๋งํฌ ๋น๋์์ ๊ฐ์ฅ ์ ์ฉํ๊ฒ ์ฌ์ฉํ ์ ์๋ค.(์ฑ
์์๋ ControllerLinkBuilder
๋ผ๊ณ ์ ํ์๋๋ฐ ์ด๊ฐ WebMvcLinkBuilder
๋ก ๋ณ๊ฒฝ) ๋งํฌ ๋น๋๋ฅผ ์ฌ์ฉํ๋ฉด ์ ์ฝ๋๋ฅผ ๋ค์๊ณผ ๊ฐ์ด ๋ํ๋ผ ์ ์๋ค.
recentResources.add(
WebMvcLinkBuilder.linkTo(WebMvcLinkBuilder.methodOn(DesignTacoController.class)
.recentTacos())
.withRel("recents"));
์ WebMvcLinkBuilder.methodOn
๋ฉ์๋๋ DesignTacoController
๋ฅผ ์ธ์๋ก ๋ฐ์ recentTacos()
๋ฉ์๋๋ฅผ ํธ์ถํ ์ ์๊ฒ ํด์ค๋ค. ๋ฐ๋ผ์ ํด๋น ์ปจํธ๋กค๋ฌ์ ๊ธฐ๋ณธ ๊ฒฝ๋ก์ recentTacos()
์ ๋งคํ ๊ฒฝ๋ก๋ฅผ ๋ชจ๋ ๊ฒฐ์ ํ๋๋ฐ ์ฌ์ฉํ๋ค.
๋ฆฌ์คํธ์ ํฌํจ๋ ๊ฐ ๋ฆฌ์์ค์ ๋ํ ๋งํฌ๋ ์ถ๊ฐํด์ค์ผ ํ๋ค. ์ด๋ ํ ์ ์๋ ๋ฐฉ๋ฒ ์ค ํ๋๋ ๋ฐ๋ณต๋ฌธ์ ๋๋ ค ์์ ๊ฐ์ ๋ฐฉ๋ฒ์ผ๋ก ๋งํฌ๋ฅผ ์ถ๊ฐํ๋ ๊ฒ์ด๋ค. ํ์ง๋ง ์ด๋ ๋ฆฌ์คํธ๋ฅผ ๋ฐํํ๋ API์ผ ๊ฒฝ์ฐ์ ๊ณ์ํด์ ๋ฐ๋ณต๋ฌธ์ด ๋ค์ด๊ฐ๊ฒ ๋๋ค.
์ด๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด ๊ฐ ๋ฆฌ์์ค๋ค์ Resource ๊ฐ์ฒด๋ก ์์ฑํ๋ ๋ฐฉ์ ๋์ ์ ๋งํฌ๋ฅผ ์ถ๊ฐ๋ก ๊ฐ์ง๊ณ ์๋ ์๋ก์ด ๊ฐ์ฒด๋ฅผ ๋ง๋ค์ด ๋ณํํ๋ ๊ณผ์ ์ ๊ฑฐ์น ๊ฒ์ด๋ค. ์ด ๋ณํ์ ๋์์ฃผ๋ ๊ฒ์ด ๋ฐ๋ก ๋ฆฌ์์ค ์ด์ ๋ธ๋ฌ์ด๋ค.
public class TacoResourceAssembler extends RepresentationModelAssemblerSupport<Taco, TacoResource>{
// ์์ ํด๋์ค๋ฅผ ํธ์ถ, TacoResource๋ฅผ ์์ฑํ๊ณ ๋ง๋ค์ด์ง๋ ๋งํฌ์ ๊ธฐ๋ณธ ๊ฒฝ๋ก๋ฅผ ๊ฒฐ์ ํ๊ธฐ ์ํด DesignTacoController๋ฅผ ์ฌ์ฉ
public TacoResourceAssembler() {
super(DesignTacoController.class, TacoResource.class);
}
// ๋ง์ฝ TacoResource์ ๊ธฐ๋ณธ ์์ฑ์๊ฐ ์กด์ฌํ๋ค๋ฉด ์๋ต ๊ฐ๋ฅ
@Override
protected TacoResource instantiateModel(Taco taco) {
return new TacoResource(taco);
}
// Taco ๊ฐ์ฒด๋ก TacoResource ์ธ์คํด์ค๋ฅผ ์์ฑํ๋ฉด์ Taco ๊ฐ์ฒด์ id ์์ฑ ๊ฐ์ผ๋ก ์์ฑ๋๋ self ๋งํฌ๊ฐ URL์ ์๋ ์ง์
@Override
public TacoResource toModel(Taco entity) {
return createModelWithId(taco.getId(), taco);
}
}
์ฑ
์์์ ResourceAssemblerSupport
๋ RepresentationModelAssemblerSupport
๋ก ๋ณ๊ฒฝ๋์๋ค.
์คํ๋ง ๋ฐ์ดํฐ REST๋ ์คํ๋ง ๋ฐ์ดํฐ์ ๋ ๋ค๋ฅธ ๋ชจ๋์ด๋ฉฐ, ์คํ๋ง ๋ฐ์ดํฐ๊ฐ ์์ฑํ๋ ๋ ํฌ์งํ ๋ฆฌ์ REST API๋ฅผ ์๋์ผ๋ก ์์ฑํ๋ค. ์ด๋ spring-boot-starter-data-rest
์์กด์ฑ๋ง ์ถ๊ฐํด์ฃผ๋ฉด ์ฌ์ฉ์ด ๊ฐ๋ฅํ๋ค. ์์กด์ฑ์ ์ถ๊ฐํ๋ฉด ์คํ๋ง ๋ฐ์ดํฐ๋ฅผ ์ฌ์ฉ ์ค์ธ ํ๋ก์ ํธ์์ REST API๋ฅผ ๋
ธ์ถ์ด ๊ฐ๋ฅํ๋ค. ๊ธฐ์กด์ ์กด์ฌํ๋ @RestController์ ์๋ ํฌ์ธํธ๊ฐ ๊ฒน์น ์ ๋ ์์ผ๋ ์ฃผ์ํด์ผ ๋๋ค.
http://localhost:8080/ingredients
์์ ์ฃผ์์ ๋ค์ด๊ฐ ๋ณด๋ฉด, ์คํ๋ง ๋ฐ์ดํฐ REST์์ ์๋-๊ตฌ์ฑ์ผ๋ก ์ด๋ฏธ API๋ฅผ ๋ง๋ค์ด ๋์๊ฒ์ ๋ณผ ์ ์๋ค.
์ ๊ทธ๋ฆผ์ ์๋์ผ๋ก ๋ง๋ค์ด์ง API์ ์ผ๋ถ๋ง ์บก์ณํ์๋ค. ์ด๋ ๊ฒ ์๋์ผ๋ก ๋ง๋ค์ด์ง ์๋ํฌ์ธํธ๋ค์ GET, POST, PUT, DELETE ๋ฉ์๋๋ฅผ ์ง์ํ๋ฏ๋ก ์ฌ๋ฌ๊ฐ์ง ์์ ์ ํ ์ ์๋ค.
์ถ๊ฐ์ ์ผ๋ก ํ ์ผ์ ์ฐ๋ฆฌ๊ฐ ์์ฑํ ์ปจํธ๋กค๋ฌ์ ์๋ํฌ์ธํธ์ ์ถฉ๋ํ์ง ์๊ฒ ์๋์ผ๋ก ์์ฑ๋๋ API์ ๊ธฐ๋ณธ ๊ฒฝ๋ก๋ฅผ ์ค์ ํด์ฃผ์ด์ผ ํ๋ค. ์ด๋ application.yml
ํ์ผ์ spring.data.rest.base-path
์์ฑ์ ์ค์ ํด์ฃผ๋ฉด ๋๋ค.
์๋์ผ๋ก API๋ฅผ ๊ตฌ์ฑํ ๋, ์ด๋ฆ์ ๊ฒฝ์ฐ ์คํ๋ง์์ ์์์ ์ ํ๊ธฐ ๋๋ฌธ์ ๊ธฐ๋ณธ์ ์ผ๋ก๋ ํด๋น ์ํฐํฐ ํด๋์ค ์ด๋ฆ์ ๋ณต์ํ์ ์ฌ์ฉํ๋ค.(taco โ tacoes, ingredient โ ingredients)
์ด๋ ์ํฐํฐ ํด๋์ค์ @RestResource
์ ๋
ธํ
์ด์
์ ์ฌ์ฉํ๋ฉด ๋๋ค.
@Data
@Entity
@RestResource(rel="tacos", path="tacos")
์์ ๊ฐ์ด ์ค์ ์ ํ๋ค๋ฉด ๊ธฐ๋ณธ์ ์ผ๋ก ์๊ธฐ๋ tacoes๊ฐ ์๋ tacos๋ก ๋ณ๊ฒฝํ ์ ์๋ค.
ํ ๋ฆฌ์์ค(๋ชจ๋ ์ํฐํฐ์ ๋งํฌ๋ฅผ ๋ณด์ฌ์ค)์ ๋ชจ๋ ๋งํฌ๋ ์ ํ์ ๋งค๊ฐ๋ณ์์ธ page, size, sort๋ฅผ ์ ๊ณตํ๋ค. ๋ฐ๋ผ์ ์ด๋ฅผ ํ๋ผ๋ฏธํฐ๋ก ๋๊ธฐ๊ฒ ๋๋ฉด ์ํ๋ ํ์ด์ง, ํ์ด์ง์ ํฌ๊ธฐ, ์ ๋ ฌ ์ํ๋ฅผ ์ ์ฉํ์ฌ ๋ณผ ์ ์๋ค.
http://localhost:8080/api/tacos?size=5&page=1
์์ ๊ฐ์ด ์์ฒญ์ ๋ณด๋ด๋ฉด ํ์ด์ง ํฌ๊ธฐ๊ฐ 5์ด๋ฉด์ 2๋ฒ์งธ ํ์ด์ง๋ฅผ ๋ณด์ฌ์ฃผ๊ฒ ๋๋ค.(ํ์ด์ง๋ 0๋ถํฐ ์์) ์ด์ธ์๋ ์ ์ฒด๊ฐ ๋ช๊ฐ์ธ์ง, ์ ์ฒด ํ์ด์ง์๋ ๋ช์ธ์ง์ ๋ํ ํ์๋ ๋ณผ ์ ์๋ค.
์คํ๋ง์ ์๋-๊ตฌ์ฑ ๊ธฐ๋ฅ์ผ๋ก ๋ง์ ์๋ํฌ์ธํธ๋ฅผ ๋ง๋ค์ด ๋์์ง๋ง, ์กฐ๊ธ๋ ๋ค๋ฅธ ๋ก์ง์ ์๋ํฌ์ธํธ๋ฅผ ์ค์ ํ๊ณ ์ถ์ ๊ฒฝ์ฐ๋ ์กด์ฌํ๋ค. ์ด๋ @RestController ์ ๋ ธํ ์ด์ ์ด ์ง์ ๋ ๋น์ ๊ตฌํํ์ฌ ์คํ๋ง ๋ฐ์ดํฐ REST๊ฐ ์๋ ์์ฑํ๋ ์๋ํฌ์ธํธ์ ๋ณด์ถฉํ ์ ์๋ค. ํ์ง๋ง ๋๊ฐ์ง๋ฅผ ๊ณ ๋ คํด์ ์์ฑํด์ผ ํ๋ค.
- ์๋ก ๋ง๋ ์๋ํฌ์ธํธ๋ ์คํ๋ง ๋ฐ์ดํฐ REST์ ๊ธฐ๋ณธ ๊ฒฝ๋ก๋ก ๋งคํ๋์ง ์๋๋ค. ๋ฐ๋ผ์, ๊ธฐ๋ณธ ๊ฒฝ๋ก๋ฅผ ํฌํจํ์ฌ ์ฐ๋ฆฌ๊ฐ ์ํ๋ ๊ธฐ๋ณธ ๊ฒฝ๋ก๊ฐ ์์ ๋ถ๋๋ก ๋งคํํด์ผ ๋๋ค. ๋ง์ฝ ๊ธฐ๋ณธ ๊ฒฝ๋ก๊ฐ ๋ฐ๋๋ฉด ํด๋น ์ปจํธ๋กค๋ฌ์ ๋งคํ ๋ํ ์ผ์น ์์ผ์ฃผ์ด์ผ ํ๋ค.
- ์๋ก ์ ์ํ ์๋ํฌ์ธํธ๋ ํ์ดํผ๋งํฌ์ ์๋์ผ๋ก ํฌํจ๋์ง ์๋๋ค.
์ปจํธ๋กค๋ฌ์ ์คํ๋ง ๋ฐ์ดํฐ REST ๊ธฐ๋ณธ ๊ฒฝ๋ก๋ฅผ ์ ์ฉํ๊ธฐ ์ํด @RepositoryRestController
์ ๋
ธํ
์ด์
์ ์ถ๊ฐํ๋ค. ์ด๋ @RestController
์ ๊ฑฐ์ ํก์ฌํ๊ฒ ์๊ฒผ๋๋ฐ ๋์ผํ๊ฒ ์ํํ์ง ์๋๋ค. @RepositoryRestController
๋ ๋ฐํ๊ฐ์ ์์ฒญ ๋ฐ๋์ ์๋์ผ๋ก ๋ฃ์ง ์๊ธฐ ๋๋ฌธ์ @ResponseBody
์ ๋
ธํ
์ด์
์ ์ถ๊ฐํ๊ฑฐ๋, ResponseEntitiy๋ฅผ ๋ฐํํด์ผ ํ๋ค.