일반적으로 브라우저에서 실행되는 자바스크립트 코드에 직접적으로 데이터베이스와 통신하는 코드를 작성해선 안됩니다.
만약 React App과 SQL 데이터베이스, Mongo DB, NoSQL 데이터베이스 등 데이터베이스와 직접 연결하여 실행하는 것은 문제가 되지 않지만 매우 불안정하고, 데이터베이스 인증 정보가 노출되는 위험성이 존재합니다.
브라우저에서 실행되는 모든 자바스크립트 코드는 사용자가 직접 접근 가능하며 읽을 수 있다는 것에 명심해야 합니다. 코드들은 개발자 도구를 통해서 확인할 수 있습니다. 이는 보안 관련 세부 사항을 노출하는 것으로 문제가 될 수 있습니다.
데이터베이스는 Backend App과 연결하여 사용해야 합니다. Backend App은 브라우저 내 실행되지 않고 다른 기기에서 데이터베이스 서버와 연결되어 통신하며 웹 사이트를 사용하는 사용자들은 Backend App 코드를 볼 수 없습니다. 그러므로 데이터베이스와 통신하기 위해 Backend App을 사용해야 합니다.
즉, React App에서는 Backend API 서버와 통신하고, Backend App이 데이터베이스와 연결되어 통신을 수행해야 합니다.
참고로 API는 "Application Programing Interface"를 뜻합니다.
API는 아주 넓은 개념으로서 어떤 작업을 수행하기 위해 명확히 정의된 "규칙"을 의미합니다. 쉽게 이야기하면 프로그램과 프로그램을 이어주는 역할, 즉 프로그램간 데이터를 주고 받기 위한 "방법"과 그 "규격"을 뜻합니다. 그리고 API 문서가 바로 이 사용법과 규격을 제공하는 문서입니다.
브라우저에서는 통신을 위해서 HTTP 요청을 사용하며 HTTP 요청과 관련된 API로는 보통 REST API 혹은 GraphQL API가 존재합니다. 이 둘은 서버가 데이터를 노출하는 방식에 대한 표준의 차이가 존재합니다.
정리하면 Frontend App은 Backend App과 연결하여 통신하고, Backend App은 DataBase와 연결이 되어 통신을 하게 됩니다. 이렇게 하는 이유는 퍼포먼스의 문제와 보안 문제로 인해 이렇게 연결됩니다.
우리는 Backend App이 정의한 통신 규칙, 즉 Backend API를 준수하여 Backend App과 통신을 함으로서 DataBase와 통신 할 수 있습니다.
리액트에서 서버 API에 Http 요청 보내는 로직의 경우 side-effect로 useEffect
훅을 통해 처리해야 합니다.
주의할 점으로는 useEffect
훅의 인수로 전달하는 콜백함수의 반환값으로는 undefined 혹은 clean-up 함수만이 가능하기 때문에 useEffect
훅의 인수로 전달할 콜백함수 자체를 async 함수로 전달하는 것은 불가능합니다. async 함수는 언제나 프로미스 객체를 반환하기 때문입니다.
useEffect(() => {
if(isLoading) {
const fetchData = async() => {
try {
const response = await fetch('https://,,,');
if (!response.ok) {
throw new Error('Error Message');
}
const data = await response.json();
// Http 응답 처리
} catch(error) {
// error 처리,,,
}
};
fetchData();
}
}, [isLoading]);
즉, 위 코드처럼 useEffect
훅 인수로 전달되는 콜백함수 내부에 async 함수를 정의하는 것은 가능하며, 내부에 정의한 async 함수를 호출하여 서버에게 Http 요청을 보낼 수 있습니다.
useEffect(() => {
if(isLoading) {
const postData = async() => {
try {
const response = await fetch('https://,,,', {
method: 'POST',
body: JSON.stringify(data),
header: {
'Content-Type': 'application/json'
}
});
if (!response.ok) {
throw new Error('Error Message');
}
const data = await response.json();
// Http 응답 처리
} catch(error) {
// error 처리,,,
}
};
postData();
}
}, [isLoading]);