---
title: "REST"
date: "2019-05-14"
tags: ["TIL","REST"]
status: archived
verified: false
---

---

2019년 웹 애플리케이션 학습 중 REST의 개념과 제약 조건을 다시 정리한 TIL입니다. 단순히 URL과 HTTP 메서드를 외우기보다 자원과 상태를 어떻게 다루는지 이해하려고 작성했습니다. 설명과 예시는 작성 당시의 관점이므로 학습 과정의 기록으로 참고해주세요.

## REST(Representational State Transfer)

* **월드 와이드 웹과 같은 분산 하이퍼미디어 시스템을 위한 소프트웨어 아키텍처의 한 형식**
* 로이 필딩(Roy Fielding)의 박사학위 논문에서 소개됨
* **REST는 네트워크 아키텍처 원리의 모음**
  * 네트워크 아키텍처 원리란 자원을 정의하고 자원에 대한 주소를 지정하는 방법 전반
  * 간단한 의미로 웹 상의 자료를 HTTP 위에서 SOAP나 쿠키를 통한 세션 트래킹 같은 별도의 전송 계층 업시 전송하기 위한 아주 간단한 인터페이스를 말함
* **REST의 원리를 따르는 시스템 == RESTful**

## REST 아키텍처에 적용되는 6가지 제한 조건

* 클라이언트/서버 구조
* 무상태(Stateless)
* 캐시 처리 가능(Cacheable)
* 계층화
* Code on demand
* 인터페이스 일관성

## RESTful

* **WEB - GET, POST**
  * **요청을 모아서 처리할 수 없다**
  * **행위에 대한 식별이 어렵다**
    * some.do, blahblah.do
* **RESTful API - GET,POST,PUT,DELETE**
  * **기존의 URI와 다르다**
  * **WEB은 확장자까지 명시하여 원하는 자원을 요청**
    * **RESTful은 확장자를 사용하지 않는다**
    * **요청을 모아서 처리할 수 있다**
  * **행위에 대한 식별이 쉬워진다(상/중/하 식으로 분류가 가능)**
  * **form은 get/post만 처리 가능**
  * **put,delete는 ajax로 처리함**
    * **요청값으로 JSON을 전달하고 응답 또한 JSON으로 되기 때문**

```html
<!-- 일반 WEB -->
<a href="요청uri.확장자">

<form method="get|post" action="some.do">
    <input type="submit"/>
</form>

<!-- RESTful -->
<a href="a/b/c">

<form action="a/b/c" method="get|post">
    <input type="submit"/>
</form>
```

* **RESTful은 URL을 가지고 자원을 식별**

```
기존 WEB : http://sist.co.kr/admin/insert.do?이름=값
RESTful : http://sist.co.kr/상위개념/하위개념/요청대상/?파라미터
```

* **Spring은 RESTful을 지원**

```java
@Controller(...) // view 중심
// 응답 데이터가 JSP로 응답

@RestController(...) // 데이터 중심
// 응답 데이터가 JSON, XML
// 웹브라우저에서 보여줄 수 없다
// 가공 필요 => JavaScript로 가공
```

* **AJAX로 PUT 요청을 보낼 때 예**
  * 전달할 Object는 JSON.stringify()를 통해 문자열로 변환 후 전달

```javascript
$.ajax({
    url:"class4/group1/member",
    dataType:"put",
    data: JSON.stringify({ 이름:"값" }),
    ...
});
```

* **HTTP body(payload)에 JSON이 담겨서 전달됨**
  * **@RequestBody를 사용해서 전달된 HTTP Body에 저장되어 전달된 JSON을 받을 수 있다**
  * **JSONParser를 이용해서 전달된 문자열 JSON을 Parsing해서 JSONObject 만들어 사용**

```java
// 그룹 맴버를 업데이트하기 위한 요청, parameter로 받으면 한개만 받을 수 있다
// JSON으로 넘어오면 여러 parameter를 전달 받을 수 있다
// form태그로는 JSON을 넘길 수 없다, AJAX로 JSON을 전달가능!

@PutMapping(value="class4/group1/member")
public String method(@RequestBody String json) {
    // JSONSimple에서 제공하는 JSONParser를 사용
    JSONParser jp = new JSONParser(json);

    // JSONParser는 JSON 형태의 문자열을 잘라내서 JSONObject로 생성
    JSONObject jo = jp.parse();

    jo.get("이름"); // 값 반환
    ...
```

* **RESTful하게 멤버를 추가하는 요청 예**
  * class4의 1조 회원 추가

```html
<form action="class4/group1/add" method="get">
    <input type="..."/>
    ...
</form>
```

* **요청을 모아서 처리할 수 없다**
  * uri가 group1/jaechan-add, group1/something-add, ... 등등 
  * **다양한 요청을 한 메소드에서 처리할 수 있다**
  * **uri 가 의미적으로 더 명확해짐**

```java
@Controller
class Test {

    @GetMapping(value="class4/group1/{id}")
    public String insert(VO) {
...
```

**REST API**
* **URI는 정보의 자원을 표현**
  * 리소스명은 동사보다는 명사를 사용
* **자원에 대한 행위는 HTTL Method(GET, POST, PUT, DELETE)로 표현**
* GET - 자원을 조회할 때 사용(retrieve)
* POST - 자원을 추가할 때 사용(create)
* PUT - 자원을 변경할 때(update)
* DELETE - 자원을 삭제할 때(delete)

## Spring에서 REST 사용 예

![05](/md/legacy-assets/til/REST/05.webp)

* **우선 일반적인 WEB의 GET/ POST 방식**
  
```html
<!-- index.jsp -->
      
<a href="method/get">GET방식</a>
<form action="method/post" method="post">
      <input type="submit" value="post 전송"/>
</form>
<form action="method/put" method="put"><!-- form으로 put/delete 요청 안됨 -->
      <input type="submit" value="put 전송"/>
</form>
```

```html
<!-- get.jsp -->
      
<h2>GET 방식요청</h2>
<br/>
<a href="javascript:history.back()">뒤로</a>
```

![01](/md/legacy-assets/til/REST/01.webp)

```html
...
<form action="method/post" method="post">
      <input type="submit" value="post 전송"/>
</form>
...
```

```java
...
      @PostMapping("/method/post")
      public String postProcess() {
            return "post";
      }
...
```

![02](/md/legacy-assets/til/REST/02.webp)

* **PUT은 form태그로 요청할 수 없다**
    * **put이라 써도 get으로 처리됨**

![03](/md/legacy-assets/til/REST/03.webp)

* **PUT은 AJAX로 요청**

```html
<script type="text/javascript">
      $(function() {
            
            $("#put").click(function() {
                  $.ajax({
                        url:"method/put",
                        type:"put",
                        dataType:"json",
                        error:function(xhr) {
                              alert("코드 : "+xhr.status+", 메시지 :  "+xhr.statusText);
                              alert(xhr.responseText);
                        },
                        success:function(json) {
                              alert(json.put);
                        }
                  });
            });
      }); // ready
</script>
...
<input type="button" id="put" value="put 전송"/>
```

```java
...
      @ResponseBody
      @PutMapping(value="/method/put",  produces="application/json;charset=UTF-8")
      public String putProcess() {
            return "{ \"put\":\"ppppput\" }";
      }
...
```

![04](/md/legacy-assets/til/REST/04.webp)

* **출처**
  * [위키](https://ko.wikipedia.org/wiki/REST)
  * [REST API 제대로 알고 사용하기](https://meetup.toast.com/posts/92)
