모든 모던 웹 앱에서 대부분은, 자신의 개인 공간을 가질 계정을 만들 수 있습니다. 여러 사용자가 동시에 웹 앱에 접근할 수 있으므로, 각자 사용자의 개인 데이터를 별도로 저장하고 어느 정보를 보여줄 지에 대하여 선택하는 메커니즘이 필요합니다. 자체적으로 광범위한 주제이므로 [user identity securely](https://en.wikipedia.org/wiki/Authentication) 관리하는 방법은 다루지 않지만, 각자가 앱에서 하나 (이상)의 은행 계좌를 만들 수 있는지 확인합니다.
이 강의를 위해 웹 앱의 [HTML templates and routing](../1-template-route/README.md)을 완료해야합니다. 또한 [Node.js](https://nodejs.org)와 [run the server API](../api/README.md)를 로컬에 설치해야 계정을 만들 데이터를 보낼 수 있습니다.
`<form>` 요소는 사용자가 대화형 컨트롤을 사용하여 데이터를 입력하고 제출할 수 있는 HTML 문서의 섹션을 캡슐화합니다. 폼 내에서 쓸 수 있는 모든 종류의 사용자 인터페이스(UI) 컨트롤이 있으며, 가장 일반적인 컨트롤은 `<input>`과 `<button>` 요소입니다.
> UI를 작성할 때 쓸 수 있는 모든 네이티브 UI 요소에 대한 아이디어를 얻으려면 [`<input>` types](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input)과 [other form controls](https://developer.mozilla.org/en-US/docs/Learn/Forms/Other_form_controls)의 전체 목록을 찾아봅시다.
> 웹에서의 [Accessibility](https://developer.mozilla.org/en-US/docs/Learn/Accessibility/What_is_accessibility)은 종종 간과되는 매우 중요한 주제입니다. [HTML5 semantic elements](https://developer.mozilla.org/en-US/docs/Learn/Accessibility/HTML) 덕분에 이를 적절하게 사용한다면 접근성 콘텐츠로 만드는 것은 어렵지 않습니다. 일반적인 실수를 피하고 책임있는 개발자가 되기 위해 [accessibility에 대하여 읽을 수](https://developer.mozilla.org/en-US/docs/Web/Accessibility) 있습니다.
`<form>`의 기본 작업은 [GET method](https://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.3)를 사용하여 현재 서버 URL에 폼을 제출하고, 폼 데이터를 URL에 직접 추가하는 것입니다. 이 방식에는 몇 가지 단점이 있습니다:
알다시피, 사용한 접근 방식에는 약간 이슈가 있습니다: 폼을 제출할 때, 앱에서 나가면서 브라우저가 서버 URL로 리디렉션됩니다. [Single-page application (SPA)](https://en.wikipedia.org/wiki/Single-page_application)을 만들고 있으므로, 웹 앱으로 모든 페이지를 다시 불러오지 않으려 합니다.
페이지를 강제로 다시 불러오지 않고 폼 데이터를 서버로 보내려면, JavaScript 코드를 사용해야 합니다. `<form>` 요소의 `action` 속성에 URL을 넣는 대신, `javascript:` 문자열이 앞에 붙은 JavaScript 코드를 사용하여 커스텀 작업을 할 수 있습니다. 이를 사용하면 이전에 끝낸 브라우저로 자동 수행한 일부 작업을 구현해야 합니다:
여기서는 `getElementById()`를 사용하여 폼 요소를 검색하고, [`FormData`](https://developer.mozilla.org/en-US/docs/Web/API/FormData) 헬퍼를 사용하여 키/값 쌍 집합으로 폼 컨트롤에서 값을 추출합니다. 그러고 [`Object.fromEntries()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/fromEntries)를 사용하여 데이터를 일반 객체로 변환하여 최종적으로 웹에서 데이터를 교환할 때, 일반적으로 사용되는 포맷인 [JSON](https://www.json.org/json-en.html)으로 데이터를 직렬화합니다.
이 함수는 어떤 일을 할까요? 먼저, 여기있는 `async` 키워드를 확인하세요. 이 함수는 [**asynchronously**](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function)하게 실행하는 코드가 포함되어 있다는 것을 의미합니다. `await` 키워드와 함께 사용하면, 비동기 코드가 실행될 때까지 기다릴 수 있습니다 - 여기에서 서버의 응답을 기다리는 것과 같습니다 - 계속하기 전에.
[![Async and Await for managing promises](https://img.youtube.com/vi/YwmlRkrxvkk/0.jpg)](https://youtube.com/watch?v=YwmlRkrxvkk "Async and Await for managing promises")
서버가 JSON으로 응답하므로, `await response.json()`을 사용하여 JSON 콘텐츠를 파싱하고 결과 객체를 반환할 수 있습니다. 이 메소드는 비동기이므로, 반환하기 전 여기에서 `await` 키워드를 사용하여 파싱하는 도중에도 오류가 발생하는지 확인합니다.
조금 길지만 도착했습니다! [browser developer tools](https://developer.mozilla.org/en-US/docs/Learn/Common_questions/What_are_browser_developer_tools)를 열고, 새 계정을 가입하면, 웹 페이지에 변경 사항이 표시되지 않으면서 콘솔에 작동을 확인할 메시지가 나타납니다.
사용자 이름을 먼저 설정하지 않고 새 계정을 가입하려하면, 서버에서 상태 코드 [400 (Bad Request)](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/400#:~:text=The%20HyperText%20Transfer%20Protocol%20(HTTP,%2C%20or%20deceptive%20request%20routing).) 오류를 반환하는 것으로 볼 수 있습니다.
데이터를 서버로 보내기 전에 할 수 있다면, 유요한 요청을 보낼 수 있도록, 미리 [validate the form data](https://developer.mozilla.org/en-US/docs/Learn/Forms/Form_validation)를 실습하는 것이 좋습니다. HTML5 포맷 컨트롤은 다양한 속성을 사용하여 빌트인 유효성 검사를 제공합니다:
-`minlength`와 `maxlength`: 텍스트 입력의 최소 및 최대 문자 수를 정의합니다.
-`min`과 `max`: 숫자 필드의 최소값과 최대값을 정의합니다.
-`type`: `number`, `email`, `file` 또는 [other built-in types](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input)처럼, 예상되는 데이터의 종류를 정의합니다. 이 속성은 폼 컨트롤의 비주얼 렌더링을 바꿀 수도 있습니다.
-`pattern`: 입력된 데이터가 유효한지 테스트하기 위해 [regular expression](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions) 패턴을 정의할 수 있습니다.
서버에 데이터를 보내기 *전에 하는* 유효성 검사를 **client-side** 유효성 검사라고 합니다. 그러나 데이터를 보내지 않고 모든 검사를 하는 것은 항상 가능하지 않습니다. 예를 들면, 서버에 요청을 보내지 않고 동일한 사용자 이름을 가진 계정이 이미 존재하는지 확인할 수 있는 방식은 없습니다. 서버에서 수행되는 추가적인 유효성 검사를 **server-side** 유효성 검사라고합니다.