
인덕대학교 A&I 동아리에서 스터디한 내용을 바탕으로 작성하였습니다.
지난 포스트에서 https://start.spring.io/ 해당 URL에 들어가
FirstSpringBoot라는 프로젝트 파일을 생성했었습니다.
이번 포스트에서는 RESTful API를 간단하게 실습해보겠습니다.
Spring Boot에는
@형태의 어노테이션(annotation)이 존재합니다.
Annotation은 사전적으로는 주석이라는 뜻이지만,
자바에서의Annotation은 코드 사이에 주석처럼 사용되면서
특별한 의미나 기능을 수행하도록 도와주는 기술입니다.
즉, 프로그램에 추가적인 정보를 제공하는 메타데이터(metadata) 역할을 합니다.
@RestController 생성어노테이션의 기능을 이해하셨다면, 이제 프로젝트 파일 안에서
@RestController를 생성해보겠습니다.
@RestController 어노테이션은 Spring Boot에서
@Controller와 @ResponseBody가 합쳐진 형태입니다.
클래스에 @RestController를 명시해주면, 해당 클래스 안에서
REST API를 생성할 수 있습니다.
그럼 실습으로
Human클래스를 만들어
클래스의 데이터를 가져오는 간단한 REST API를 생성해보겠습니다.
먼저 firstSpringBoot 프로젝트 파일 안에 들어가
human이라는 패키지를 생성해주시고,
그 안에 controller 패키지와 model 패키지를 생성해주었습니다.
이후 model 패키지 안에는 Human.kt를,
controller 패키지 안에는 HumanController.kt 파일을 생성해주신 뒤
다음과 같은 코드를 각각 작성해주시면 됩니다.
//human.kt
class Human (
val name :String,
val age : Int,
var id : Int,
)
//humanController.kt
@RestController()
@RequestMapping("/humans")
class HumanController {
final var humans = mutableListOf<Human>()
init {
humans.addAll(
listOf(
Human(name = "짱구", age = 5, id = 1),
Human(name = "맹구", age = 5, id = 2),
Human(name = "철수", age = 5, id = 3),
Human(name = "유리", age = 5, id = 4),
)
)
}
@GetMapping
private fun getHumanList(): ResponseEntity<List<Human>> {
return ResponseEntity
.status(HttpStatus.OK)
.body(humans)
}
}
이후 실행해보시면
Postman에서
http://localhost:8080/humans 경로를 통해
다음과 같은 결과를 얻으실 수 있습니다.

이것이 스프링 부트에서 어노테이션을 사용한
@GetMapping입니다.
GET은 데이터를 읽는 메서드로,
일반적으로 데이터베이스에 저장된 내용을 조회할 때 사용합니다.
위 코드에서는 리스트를 생성한 뒤, 그 리스트를 ResponseEntity 안에 담아 반환하고 있습니다.
그리고 해당 리스트를 GET으로 요청하면 HttpStatus.OK를 함께 반환하게 됩니다.
즉, 데이터를 조회하는 가장 기본적인 방식이라고 보시면 됩니다.
그렇다면
HttpStatus응답 코드도 함께 알아둘 필요가 있습니다.
왜냐하면 HTTP 메서드는 기본적으로 응답 코드를 가지고 있고,
API 요청 결과에 따라 적절한 응답 코드를 반환해야 하기 때문입니다.
이번 REST API 코드에서 자주 사용하게 될 응답 코드는 다음과 같습니다.
| 응답 코드 | 반환 |
|---|---|
| 200 | OK, 요청이 성공하였습니다. |
| 201 | CREATED, 요청이 성공하여 새로운 데이터가 생성되었습니다. |
| 202 | ACCEPTED, 요청은 전달받았지만 아직 처리 중입니다. |
| 204 | NO_CONTENT, 요청은 성공했지만 반환할 데이터가 없습니다. |
POST메서드는 데이터 생성을 요청하는 메서드입니다.
조금 더 정확하게 말씀드리면,
부모 자원 아래에 새로운 하위 리소스를 생성하는 행위라고 볼 수 있습니다.
기본적으로 200 OK 응답코드를 사용할 수도 있지만,
새로운 데이터가 생성되었음을 더 명확하게 표현하기 위해
201 CREATED 응답코드를 반환하는 것이 더 적절합니다.
그럼 아래 코드를 Controller에 추가해보겠습니다.
//humanController.kt
@PostMapping
fun postHuman(@RequestBody human : Human) : Human {
humans.add(human)
return human
}


해당 코드는 리스트 안에 JSON 데이터를 넘겨주면
그 형식에 맞춰 새로운 데이터를 리스트 안에 추가해줍니다.
그리고 생성이 완료되면201 CREATED응답코드를 반환하는 것을 확인하실 수 있습니다.
이것이 바로POST의 기본 원리입니다.
PUT메서드는 데이터의 수정을 요청하는 메서드입니다.
다만 입력한 파라미터에 해당하는 데이터가 존재하지 않는 경우에는
새로운 데이터를 생성할 수 있도록 구현할 수도 있습니다.
기본적으로는 200 OK 응답코드를 가지지만,
새로운 데이터가 생성되는 경우에는 POST와 마찬가지로
생성에 해당하는 응답을 반환하게 됩니다.
//humanController.kt
@PutMapping("/{id}")
fun putHuman(@PathVariable id: String, @RequestBody human: Human): ResponseEntity<Human> {
var index: Int = -1
for (h in humans) {
if (h.id == id.toLong()) {
index = humans.indexOf(h)
humans[index] = human
}
}
return if (index != -1) ResponseEntity.status(HttpStatus.OK).body(human) else postHuman(human)
}


해당 코드는 경로에 있는
id값을 기준으로 리스트에서 데이터를 찾은 뒤,
그 인덱스에 있는 데이터를 수정하는 코드입니다.
만약 해당 데이터가 없다면 새로 생성하도록 동작합니다.
경로 값을 가져오기 위해서는 @PathVariable을 붙여주셔야 합니다.
마지막으로
DELETE메서드는 데이터 삭제를 요청하는 메서드입니다.
일반적으로 데이터베이스에 저장된 내용을 삭제할 때 사용하며,
기본적으로 200 OK 응답코드를 가질 수 있지만
상황에 따라 204 NO_CONTENT를 반환할 수도 있습니다.
//humanController.kt
@DeleteMapping("/{id}")
fun deleteHuman(@PathVariable id : String) : ResponseEntity<Any> {
humans.removeIf{ it.id == id.toLong() }
return ResponseEntity.status(HttpStatus.NO_CONTENT).build()
}


DELETE도 마찬가지로 해당 경로의id값을 기준으로
리스트에서 데이터를 삭제하는 간단한 코드입니다.
삭제가 완료되면 응답코드204 NO_CONTENT를 반환해줍니다.
REST API를 사용하기 위해서는
Annotation을 올바르게 사용해야 하며,
수행 내용에 따라 정확한HttpStatusCode를 함께 반환해주어야 합니다.
기본 개념인 만큼 꼭 잘 기억해두시면 좋겠습니다.
해당 코드들은 GitHub에서 확인하실 수 있습니다.
https://github.com/stdiodh/SpringBoot