# 서버와 비동기로 상호작용하기

웹 페이지를 새로고침하지 않고 서버와 상호작용할 때 비동기적인 방식을 사용하기 때문이다.

'자바스크립트를 통해 서버에 비동기로 요청하는 것'

서버와 비동기로 상호작용하는 것을 확인하기 위해 다음과 같은 코드 작성

* 클라이언트 코드 : HTML 페이지 내에 XHR을 사용하여 서버로 AJAX 요청을 하는 코드
* 서버 코드 : AJAX 요청에 대한 간단한 응답을 하는 컨트롤러 코드

```java
<html>
    <head>
        <meta charset = "utf-8">
    </head>
    <body>
        <script>
            function onReadyStateChange(event) {
                if (ajaxRequest.readyState === XMLHttpRequest.DONE) {
                    if (ajaxRequest.status === 200) {
                        console.log(ajaxRequest.responseText);
                    } else{
                        console.log("request failed");
                    }
                }
            }
            
            const ajaxRequest = new XMLHttpRequest();

            ajaxRequest.onreadystatechange = onReadyStateChange;
            ajaxRequest.open("GET", "/get-with-no-parameter");
            ajaxRequest.send();
        </script>
    </body>
</html>
```

onReadyStateChange 함수는 밑에 ajaxRequest의 onreadystatechange라는 변수에 저장된다.

이것은 앞서 설명했던 것처럼 자바스크립트에서는 함수가 일급 시민이기 때문에 가능한 것이다. 이렇게 하면 onReadyStateChange() 함수는 ajaxRequest에서 readystatechange라는 이벤트가 발생했을 때 호출된다.

이처럼 특정 이벤트가 발생했을 때 호출되는 함수를 이벤트 핸들러 라고 하며, 현재와 같은 상황에서는 통상적으로 'onReadyStateChange()를 ajaxRequest.onreadystatechange의 이벤트 핸들러로 등록했다고 표현한다. 여기서 이벤트란 애플리케이션상에서 발생할 수 있는 어떤 사건을 이야기한다. 예를 들어 사용자가 마우스로 클릭하는 것도 하나의 이벤트이고, onclick 같은 이름으로 이벤트 핸들러를 등록할 수도 있다. 여기서는 ajaxRequest의 readystate가 변경(change)되는 것이 이벤트이다. 정리하자면, onReadyStateChange() 함수는 ajaxRequest의 readystate가 변경될 때 호출되도록 이벤트 핸들러로 등록되었다.

XHR 객체를 생성하여 AJAX 요청을 하는 내용이 있다. 생성한 XHR 객체는 ajaxRequest라는 상수에 저장하고, 위에서 선언해 준 onReadyStateChange() 함수를 ajaxRequest.on readystatechange에 이벤트 핸들러로 등록했다. 이벤트 핸들링을 위한 필드에는 onreadystatechange 외에도 onabort, onerror, onload, ontimeout 등이 있는데 이 역시 개발 중 필요한 시점에 찾아봐도 늦지 않다.

open() 함수는 XHR 객체의 요청을 초기화한다. 여기서는 'GET' 메서드, 그리고 '/get-with-no-parameter'라는 경로로 요청하는 AJAX 요청을 초기화하고 있다. '요청을 초기화'한다라는 말은 '요청을 준비한다'정도의 의미로 생각하자.

이어서 send() 함수가 실행될 때 비로소 AJAX 요청이 날아간다. send()는 AJAX 요청을 하는 즉시 반환되고, AJAX 요청에 대한 응답은 send() 함수와 무관하다. 응답은 앞서 선언했던 onReadyStateChange()에서 처리하게 된다. XHR로 AJAX 요청을 하면 ajaxRequest, readyState가 바뀌면서 ajaxRequest.onreadystatechange에 등록된 이벤트 핸들러가 실행되기 때문이다. readyState는 다음과 같은 상태를 가질 수 있다.

readyState 상태의 종류

| 상태                | 값 | 설명                                                    |
| ----------------- | - | ----------------------------------------------------- |
| UNSENT            | 0 | XHR 객체가 생성된 후 open() 함수를 호출하지 않은 상태                   |
| OPENED            | 1 | open() 함수가 호출된 상태                                     |
| HEADERS\_RECEIVED | 2 | send() 함수가 호출된 상태 또는 HTTP 응답 헤더와 상태 코드까지만 사용할 수 있는 상태 |
| LOADING           | 3 | HTTP 응답의 body를 다운로드하고 있는 상태                           |
| DONE              | 4 | XHR 객체의 AJAX 요청과 응답이 모두 완료된 상태                        |

JSON을 주고받는 AJAX

* 즐겨찾기는 이름과 URL로 구성한다.
* 즐겨찾기를 등록하는 기능과 현재 등록된 모든 즐겨찾기 목록을 조회하는 기능만 존재한다.
* 즐겨찾기를 등록하는 기능과 모든 즐겨찾기 목록을 조회하는 기능은 AJAX로 동작하여 새로고침하지 않도록 한다.&#x20;

1. 즐겨찾기에 대한 JSON은 다음과 같이 정의&#x20;

```
{
    "name" : "구글",
    "url" : "http://www.google.com/"
}
```

2. 즐겨찾기를 등록하는 기능을 할 HTTP 메서드와 API의 경로를 정의한다.

* POST 메서드 , /bookmark : 즐겨찾기 등록
* GET 메서드, /bookmarks : 즐겨찾기 목록 조회

```
public class Bookmark {
    public String name;
    public String url;
}
```
