[Spring Boot Up & Running] Chapter 03. 첫 번째 REST API

Falco·2023년 7월 28일

Spring Boot Up&Running

목록 보기
3/8
post-thumbnail

대부분의 어플리케이션은 프론트엔드 UI를 통해 백엔드 클라우드 리소스를 사용자에게 노출시킵니다.

목차

3.1 API를 왜 사용하고 어떻게 사용할까요?

모놀리식 어플리케이션

모든 것을 한곳에서 실행하는 어플리케이션을 의미합니다.
단일 패키지로도 수많은 기능을 제공하는 어플리케이션은 아직도 유효합니다.

다음은 모놀리식 어플리케이션이 필요한 예제입니다.

  • 도메인과 도메인의 경계가 모호할 때
  • 제공된 기능이 긴밀하게 결합됐으며, 모듈 간 상호작용에서 유연함보다 성능이 절대적으로 더 중요할 때
  • 관련된 모든 기능의 어플리케이션 확장 요구사항이 알려져 있고 일관적일 때
  • 기능이 변동성이 없을 때, 즉 변화가 느리거나 변화 범위가 제한적일 때와 둘 다일 때

인터넷은 통신을 위한 수단으로 만들어졌습니다. 중대한 장애가 발생해도 시스템 간 통신이 유지되도록 설계하였고, 이를 통해 시스템을 분산하여 마이크로서비스 분산 시스템을 통해 언제든 통신이 가능하도록 하였습니다.

3.2 REST가 무엇이며, 왜 중요할까요?

API

API는 개발자가 작성한 사양/인터페이스입니다. API를 통해 라이브러리, 다른 어플리케이션, 서비스 같은 다른 코드를 사용할 수 있습니다.

REST

REST는 Representational State Transfer의 약어로 쉽게 설명하자면

예를들어
어플리케이션 A와 어플리케이션 B가 통신할 때, A는 B에서 통신 시점의 현재 상태를 가져옵니다.
(AB가 이후에도 상태를 유지하리라고 가정하지 않습니다.) AB에 요청할 때마다 관련 상태의 표현을 제공합니다.

이러한 동작 방식은 생존가능성회복탄력성을 향상시킵니다. 이렇게 처리하는 이유는 통신 문제가 발생하거나 B가 충돌해 재시작돼도, A와 상호작용한 현재 상태를 잃어버리지 않기 때문입니다. A가 다시 요청해 두 어플리케이션이 중단된 곳에서 통신을 이어갑니다.

일반적인 개념으로 이는 무상태(stateless) 어플리케이션/서비스라고 합니다.

스프링부트는 REST한 API를 활용하여 통신이 끊겨도 계속하여 서비스를 제공합니다.

3.3 API, HTTP 메서드 스타일

REST API == RESTful API

REST API는 주로 다음의 HTTP메서드를 기반으로 합니다.

  • POST
  • GET
  • PUT
  • PATCH
  • DELETE

실제 실습해보기

간단한 도메인 만들기

data class Coffee(
        val id: Int,
        val name: String,
)

Rest API 만들어보기

@RestController
@RequestMapping("/coffees")
class CoffeController {

    private val coffees = mutableListOf<Coffee>(
            Coffee(1, "아메리카노"),
            Coffee(2, "카페 라떼"),
            Coffee(3, "모카"),
    )

    @GetMapping
    fun getCoffees(): List<Coffee> {
        return coffees
    }

    @GetMapping("/{id}")
    fun getCoffeById(@PathVariable id: String): Coffee {
        return coffees.find { it.id.toString() == id } ?: throw IllegalArgumentException("그런 커피는 없어요~")
    }

    @PostMapping("/")
    fun insertCoffee(@RequestBody coffee: Coffee): ResponseEntity<Coffee> {
        coffees.add(coffee)
        return ResponseEntity(coffee, HttpStatus.CREATED)
    }

    @PutMapping("/{id}")
    fun putCoffee(@PathVariable id: String, @RequestBody coffee: Coffee): ResponseEntity<Coffee> {
        val index = coffees.indexOf(coffees.find { it.id.toString() == id })
        return if (index == -1) {
            coffees.add(coffee)
            ResponseEntity(coffee, HttpStatus.CREATED)
        } else {
            coffees[index] = coffee
            ResponseEntity(coffee, HttpStatus.OK)
        }
    }

    @DeleteMapping("/{id}")
    fun deleteCoffee(@PathVariable id: String) {
        coffees.remove(coffees.find { it.id.toString() == id })
    }

}

궁금했던 것

RestController란?

스프링프레임워크에서 사용 가능한 어노테이션이며, 컨트롤러 클래스에 @RestController를 붙이면, 컨트롤러 클래스 하위 메서드에 @ResponseBody 어노테이션을 붙이지 않아도 문자열과 JSON 등을 전송할 수 있습니다

@GetMapping이란?

RequestMapping(value = "/coffees", method = RequestMethod.GET)이라는 긴 코드의 보일러 플레이트를 줄여 가독성을 늘린 형태입니다.

ResponseEntity란?

ResponseEntity란, httpentity를 상속받는, 결과 데이터와 HTTP 상태 코드를 직접 제어할 수 있는 클래스입니다.

return ResponseEntity(coffee, HttpStatus.CREATED)

다음과 같은 코드는 200의 HTTP코드와 함께 coffee 객체를 json형태로 반환합니다.
-> (ReponseEntity가 HttpEntity를 상속 받았기 때문에)

profile
강단있는 개발자가 되기위하여

0개의 댓글