이 글에서는 AJAX가 왜 존재하는지 먼저 이해하고, Rails 프로젝트에서 실제로 어떻게 활용할 수 있는지 차근차근 살펴보겠습니다.
웹사이트에 접속하면 무슨 일이 일어날까요?
서버로부터 페이지가 로딩됩니다. 하지만 새로운 정보를 확인하려면 페이지를 새로고침하거나, 다른 페이지로 이동하는 링크를 클릭해야 합니다.
이것이 바로 동기식(Synchronous) 흐름입니다.
새로운 데이터는 서버에 새로운 페이지를 요청했을 때에만 표시됩니다.
그런데...
페이지 새로고침 없이 언제든 백엔드에서 데이터를 가져와 현재 페이지의 원하는 부분만 업데이트하고 싶다면 어떻게 해야 할까요?
바로 이럴 때 AJAX가 등장합니다.
AJAX는 Asynchronous Javascript & XML(비동기 자바스크립트와 XML)의 약자입니다.
웹 프레임워크와 독립적인 기술이지만, Rails는 AJAX를 아주 훌륭하게 지원합니다. 지금부터 하나씩 알아보겠습니다.
단, 앱에 AJAX를 추가하면 복잡도가 올라간다는 점은 미리 유념해 두세요.
직접 AJAX 요청 보내기
AJAX는 두 부분으로 구성됩니다. 브라우저에서 자바스크립트로 보내는 '요청'과, 루비 앱에서 처리하는 '응답'입니다.
순수 자바스크립트로도 AJAX 요청을 보낼 수 있지만, boilerplate 코드가 너무 많아 일반적으로는 jQuery 같은 자바스크립트 라이브러리를 사용합니다.
jQuery 요청은 다음과 같이 작성합니다:
$.get( "/vegetables", function(data) {
alert("Vegetables are good for you!");
});
하지만 Rails 5.1부터는 jQuery가 기본 포함되지 않습니다(필요하다면 다시 추가할 수 있습니다).
참고: jQuery로 POST 요청을 보내면
InvalidAuthenticityToken오류가 발생할 수 있습니다. 이는 보안 조치로서 현재 페이지의csrf-token을 함께 전송해야 한다는 의미입니다. 반면Rails.ajax를 사용하면 이 과정이 자동으로 처리됩니다.
해결책이 있습니다!
Rails에는 자체 AJAX 함수가 내장되어 있습니다:
Rails.ajax({
url: "/books",
type: "get",
data: "",
success: function(data) {},
error: function(data) {}
})
기억하세요. 이 코드 역시 브라우저 쪽, 즉 요청 측면에 해당합니다.
즉, 이것은 자바스크립트 코드라는 뜻입니다.
Rails에서 이 AJAX 기능은 'Unobtrusive JavaScript', 줄여서 'UJS'라고 불리는 기술을 통해 제공됩니다.
AJAX로 파셜(Partial) 업데이트하기
AJAX로 받아온 데이터를 이용해 페이지의 일부분만 업데이트하려면 크게 두 가지 방법이 있습니다.
- 자바스크립트 + ERB 뷰를 작성하여 해당 요소를 업데이트하는 방법
- 컨트롤러에서 새 HTML을 문자열로 담은 JSON 응답을 반환한 뒤, 자바스크립트로 요소를 업데이트하는 방법
사실 세 번째 방법도 존재합니다.
JSON으로 데이터만 반환하고, 그 데이터를 바탕으로 자바스크립트에서 HTML 요소를 생성하는 방식입니다.
React 같은 JS 프레임워크가 바로 이 영역에서 힘을 발휘합니다.
개인적으로는 이런 프레임워크가 불필요한 복잡성을 더한다고 생각합니다.
하지만 순수 자바스크립트만으로도 충분히 처리할 수 있습니다!
바로 1번과 2번 방법입니다. 지금은 이 두 가지에 집중해 보겠습니다 🙂
자바스크립트 뷰 예시:
Rails.$('.random-number')[0].innerHTML = ("<%= j (render partial: 'random') %>")
j는escape_javascript의 별칭(alias)입니다.
jQuery 예시:
$('.random-number').html("<%= j (render partial: 'random') %>")
html과 innerHTML은 모두 대상 요소의 내용을 통째로 교체합니다.
교체 대신, 리스트에 새 요소를 추가(append)하는 방식을 선택할 수도 있습니다.
이 코드는 .js.erb 확장자를 가진 파일, 즉 현재 액션 이름과 동일한 이름(예: create.js.erb)으로 views 폴더 안에 저장하면 됩니다.
컨트롤러에서는 다른 뷰와 마찬가지로 이 뷰를 렌더링하면 됩니다.
이제 AJAX 호출이 실행되면 이 자바스크립트 코드가 자동으로 동작하며 HTML을 업데이트합니다.
이어서 두 번째 방법을 살펴보겠습니다.
컨트롤러 코드:
render json: { html: render_to_string(partial: 'random') }
그리고 자바스크립트 코드에서:
Rails.ajax({
url: "/books",
type: "get",
success: function(data) { Rails.$(".random-number")[0].innerHTML = data.html; }
})
이것도 또 하나의 유효한 방법입니다!
그렇다면 무엇을 사용해야 할까요?
DHH(Rails 창시자)는 첫 번째 방법을 선호하며, 이를 'SJR(Server-Generated Javascript)'이라고 부릅니다.
Rails가 의도한 방식은 아마 이것일 겁니다. 다만 직접 두 방식(SJR과 render_to_string)을 모두 시험해 보고, 자신의 프로젝트에 더 잘 맞는 쪽을 선택하는 것도 좋은 접근입니다.
HAML로 JS 뷰를 작성하는 방법
자, 이번에는 HAML 사용자라고 가정해 봅시다.
이 SJR 기법으로 .js.haml 뷰를 렌더링할 수 있을까요?
네, 가능합니다!
예시:
- content = j (render partial: "random")
Rails.$('.random-number')[0].innerHTML = ("#{content}")
ERB 버전보다는 문법이 약간 더 지저분하지만, 실제로 잘 동작합니다.
페이지 새로고침 없이 Rails 폼 제출하기
AJAX로 폼을 제출하고 싶다면, 굳이 AJAX 요청 코드를 직접 작성할 필요가 없습니다.
Rails가 대신 처리해 줍니다.
방법은? form_for에 remote: true 옵션을 추가하면 됩니다.
예시:
<%= form_for @fruit, remote: true do |f| %> <%= f.label :name, 'Fruit' %> <%= f.text_field :name %> <%= f.submit 'Create' %> <% end %>
이제 'Create' 버튼을 클릭하면 Rails가 자동으로 AJAX 요청을 전송하며, 페이지는 새로고침되지 않습니다.
유효성 검증 오류를 표시하고 싶다면, 기존 오류 메시지를 새 오류로 교체하는 자바스크립트 뷰(.js.erb 파일)를 만들어 렌더링해야 합니다.
앞서 'AJAX로 파셜 업데이트하기' 섹션에서 본 예시와 동일한 방식입니다.
참고로 이 remote 옵션은 링크에도 적용할 수 있으므로, AJAX delete 요청도 손쉽게 구현할 수 있습니다.
예시:
<%= link_to "Delete", book_path(book), { method: "delete", remote: true, data: { confirm: "Are you sure?" } }
응답은 자바스크립트 뷰로 처리할 수 있습니다.
HTML 요청(페이지 새로고침)과 AJAX 요청을 모두 처리해야 한다면, respond_to 메서드를 활용해야 합니다.
예시:
respond_to do |f|
f.html { redirect_to :index }
f.js
end
이런 경우에는 Turbolinks에 맡기는 편이 더 간단할 수 있습니다.
AJAX 요청과 컨트롤러의 redirect_to(respond_to 없이)를 그대로 두면, Turbolinks가 페이지를 새로고침하지 않고 내용만 교체해 줍니다.
AJAX가 작동하지 않나요? 디버깅 팁
AJAX 요청이 정상적으로 동작하지 않는다면 디버깅이 필요합니다.
먼저 브라우저 개발자 도구를 여세요.
콘솔(Console) 패널에서 자바스크립트 오류가 있는지 확인하고, 발견된 오류를 수정합니다.
또한 코드에서 대상으로 삼은 CSS 선택자가 정확한지, 오타는 없는지도 반드시 점검하세요.
다음으로 Rails 로그에 에러가 기록되어 있는지 확인합니다.
마지막으로, 올바른 뷰가 실제로 렌더링되고 있는지 검토하세요.
이 과정을 순서대로 따라가면 AJAX 요청이 실패하는 원인을 찾아 해결할 수 있습니다.
정리
이번 글에서는 비동기 요청(Asynchronous Request)을 가능하게 해주는 웹 개발 기술인 AJAX에 대해 배웠습니다.
Rails에서 이를 구현하는 다양한 방법도 함께 살펴보았습니다. AJAX는 일반적인(자바스크립트 프레임워크 없이 구축한) Rails 앱을 만들 때 반드시 필요한 것은 아니지만, 개발자의 도구 상자에 꼭 들어있으면 든든한 기술입니다.
이 글이 도움이 되었다면 글을 공유해서 더 많은 사람들이 혜택을 볼 수 있도록 해주세요 🙂
읽어주셔서 감사합니다!