스프링 | REST API

Salt·2023년 6월 27일

REST API

클라이언트와 서버간의 상호작용을 더 단순하게 하고, 쉽게 확장할 수 있는 아키텍처

  1. 무상태성 Stateless: 서버는 클라이언트의 이전 요청에 대한 정보를 저장하지 않습니다. 각 요청은 필요한 모든 정보를 포함해야 합니다.
  2. 캐시 Cacheable: 클라이언트는 응답을 캐시할 수 있으며, 캐싱된 응답은 향후 동일한 요청에 재사용될 수 있습니다.
  3. 클라이언트 서버 Client-Server: 클라이언트와 서버는 독립적으로 구축되고 운영되며, 각각의 역할에 집중할 수 있습니다.
  4. 계층화 Layered System: 시스템은 여러 계층으로 구성될 수 있으며, 각 계층은 독립적으로 변경 및 발전할 수 있습니다.
  5. 코드온디맨드 Code on Demand (optional): 서버는 필요에 따라 클라이언트에 실행 가능한 코드를 제공할 수 있습니다.

REST URI 설계 규칙

  1. 명사 사용: 리소스를 대표하는 URI는 명사를 사용해야 합니다. 동사는 HTTP 메서드를 사용하여 표현됩니다.
  2. 복수형 사용: 리소스를 대표하는 URI는 복수형을 사용해야 합니다.
  3. 계층 구조 사용: 리소스 간의 관계를 표현하기 위해 계층 구조를 사용합니다. 예를 들어, /users/1/posts와 같이 표현할 수 있습니다.
  4. URI에는 소문자 사용: URI는 소문자로 작성하고, 단어 구분을 위해 하이픈(-)을 사용합니다.
  5. Query Parameters 사용: URI에 필터, 정렬, 페이징 등의 메타데이터를 전달하기 위해 쿼리 파라미터를 사용합니다.

REST HTTP 메서드

  1. GET: 조회 ex. GET /users GET /users/1 GET /users/1/posts GET /users/1/posts/2
  2. POST: 생성 ex. POST /users POST /users/1/posts
  3. PUT: 수정 ex. PUT /users/1
  4. PATCH: 일부만 수정 ex. PATCH /users/1
  5. DELETE: 삭제 ex. DELETE /users/1

이렇게 하면 어떤 대상에 대한 작업인지 파악할 수 있다. 보자마자 무슨 기능인지 알 수 있다.

그래서 REST방식을 쓰는 것이다.

MVC의 문제점

동기식이다. 즉, 모든 절차가 다 수행되어야 실행되기 때문에 무겁다.

화면을 로딩할 때마다 처음부터 다 그림.

그래서 비동기식이 나왔다. 인스타처럼 무한스크롤이랑 비슷하기 때문에

실행 딜레이가 없고, 가볍다

그래서 REST를 써야한다.

REST API Controller

@RestController // 위 어노테이션 2개를 한번에 처리
@RequestMapping("/resttest")
public class RestApiController {

    // REST 컨트롤러는 크게 json을 리턴하거나, String을 리턴하게 할 수 있다.
    @RequestMapping(value = "/hello", method = RequestMethod.GET)
    public String hello() {
        return "안녕하세요";
    }

    // 문자 배열도 리턴 가능
    @RequestMapping(value = "/foods", method = RequestMethod.GET)
    public List<String> food() {
        List<String> foodList = List.of("탕수육", "똠양꿍", "돈카츠");
        return foodList;
    }

    @RequestMapping(value = "/person", method = RequestMethod.GET)
    public PersonDTO psrson() {
        PersonDTO p = PersonDTO.builder().id(1L).name("좋코더").age(20).build();
        return p;
    }

    // "상태코드까지"(헤더,본문 등 HTTP응답을) 함께 리턴할 수 있는 리턴자료형 ResponseEntity<>
    @GetMapping("/person-list")
    public ResponseEntity<?> personList() {
        PersonDTO p = PersonDTO.builder().id(1L).name("까까").age(10).build();
        PersonDTO p2 = PersonDTO.builder().id(2L).name("무무").age(20).build();
        PersonDTO p3 = PersonDTO.builder().id(3L).name("나나").age(30).build();
        List<PersonDTO> personList = List.of(p, p2, p3);

        // .ok는 "200코드"를 반환하고, 뒤에 연달아 붙은 body()에 실제 리턴자료를 입력
        return ResponseEntity.ok().body(personList);
    }

    // @RequestBody, @ResponseBody : HTTP 요청,응답 -> 자바,json으로 변환 : 직렬화, 역직렬화
    @RequestMapping(value = "/bmi", method = RequestMethod.GET)
    public ResponseEntity<?> bmi(BmiDTO bmi) {     // 커맨드 객체

        // 예외처리
        if(bmi.getHeight() == 0) {
            return ResponseEntity
                    .badRequest()   // 400
                    .body("키 부분에 0을 넣어 계산이 안 됩니다.");
        }

        double result = bmi.getWeight() / ((bmi.getHeight()/100) * (bmi.getHeight()/100));

        // 헤더 추가
        HttpHeaders headers = new HttpHeaders();
        headers.add("fruits", "melon");
        headers.add("lunch", "pizza");

        return ResponseEntity
                .ok()   // 200
                .headers(headers)   // 헤더 (필수는아님)
                .body(result);  // 사용자에게 보여질 데이터
    }

    // Postman 활용한 json을 파라미터로 전송한 요청
    @RequestMapping(value = "/bmi2", method = RequestMethod.GET)
    public ResponseEntity<?> bmi2(@RequestBody BmiDTO bmi) {     // 무조건 파라미터를 json으로 받을 거다

        // 예외처리
        if(bmi.getHeight() == 0) {
            return ResponseEntity
                    .badRequest()   // 400
                    .body("키 부분에 0을 넣어 계산이 안 됩니다.");
        }

        double result = bmi.getWeight() / ((bmi.getHeight()/100) * (bmi.getHeight()/100));

        // 헤더 추가
        HttpHeaders headers = new HttpHeaders();
        headers.add("fruits", "melon");
        headers.add("lunch", "pizza");

        return ResponseEntity
                .ok()   // 200
                .headers(headers)   // 헤더 (필수는아님)
                .body(result);  // 사용자에게 보여질 데이터
    }

}

REST 컨트롤러는 크게 json을 리턴하거나, String 또는 문자배열을 리턴할 수 있다.

ResponseEntity<> : 상태코드까지(헤더,본문 등 HTTP응답을) 함께 리턴할 수 있는 리턴자료형

@RequestBody, @ResponseBody : HTTP 요청,응답 -> 자바,json으로 변환 (직렬화, 역직렬화)

Postman을 활용하면 json을 파라미터로 받아서 요청할 수 있다.

JSON

가벼운 텍스트 기반의 서버와 클라이언트가 교환하는 형식으로 키-밸류 쌍으로 구성됨

0개의 댓글