Express
- Node.js의 웹 애플리케이션 프레임워크
- Node.js는 크롬의 V8엔진을 통해 브라우저가 아닌 자바스크립트로 서버를 구축한 후
그 서버에서 자바스크립트가 작동되도록 해주는 런타임 플랫폼 - Express는 이러한 Node.js를 기반으로 웹 애플리케이션을 만들기위한 프레임워크
- 💡정리하자면 Node.js를 사용하여 쉽게 서버를 구성할 수 있게 만든 클래스와 라이브러리의 집합체
자바스크립트 + Node.js를 이용한 Web API 만들기
- 1. 설치 ➡️npm install -g express-generator
⚠️ 프로젝트는 다른 리액트프로젝트의 하위가 아닌 새 프로젝트로 생성해야한다.
-g 옵션 : global로 전역옵션으로 설치해달라는 것
$ npm install -g express-generator
npm warn deprecated mkdirp@0.5.1: Legacy versions of mkdirp are no longer supported. Please update to mkdirp 1.x. (Note that the API surface has changed to use Promises in 1.x.)
added 10 packages in 954ms
- 설치완료문구
- 2. 프로젝트명 설정 ➡️ express todo-api express : express 프로젝트를 생성함을 의미
- 3. 해당 디렉토리로 이동 ➡️todo-api
- 4. 모듈 설치 ➡️npm install 이 디렉토리 안에 node_modules 디렉토리가 없으므로 필요 모듈 다운로드
포트 Port 수정
- bin 디렉토리의 www.js를 들어가보면 var port로 3000번이 설정되어있음
- 포트번호는 수정 가능 (사용 중인 포트번호를 제외한 다른 포트번호로 수정해야함)
/**
* Get port from environment and store in Express.
*/
var port = normalizePort(process.env.PORT || '1577');
app.set('port', port);
- 1577로 수정
- ▶️npm start로 서버를 띄워봄
접속방법 : “localhost:1577” 검색
Express 초기 페이지
- routes → index.js 를 확인
var express = require('express');
var router = express.Router();
/* GET home page. */
router.get('/', function(req, res, next) {
res.render('index', { title: 'Express' });
});
module.exports = router;
- title이 바뀌면 서버를 다시 시작해야함 (express는 내용이 변경되어도 인지를 못하기때문)
- router.get(”/”, function(req, res, next)
➡️index.js를 열게됨 (1577로 요청했을 경우 기본페이지를 의미)
- router.render('index', {title: 'Express'});
➡️기본으로 열릴 홈페이지를 'index'페이지로 지정
➡️router는 페이지를 의미
Express 초기 페이지 - 수정
/* GET home page. */
router.get('/NewPage', function(req, res, next) {
res.render('index', { title: 'NewPageManager' });
});
- /NewPage 와 title : 'NewPageManager' 로 임의로 바꿔주면
- localhost:1577/NewPage 접속을 통해 "NewPage 페이지"를 열 수 있음
- req : request 요청, res : response 응답
(요청에대한것은 req. 으로 구현, 응답에대한 것은 res. 으로 구현) - res.render
➡️페이지로 응답하겠다는 의미 (response)
- router.get('/NewPage', function(req, res, next)
➡️get()은 웹을 요청할때 GET방식은 URL을 통해 요청하는 방식
따라서 get으로 URL을 /NewPage 로 설정
➡️localhost:1577/NewPage 로 접속 가능
GET 방식 예시
<form action= “/action_page.php” method=”get”>
<label>...</label>
</form>
- HTML의 form태그에서 method속성이 있는데 이 method가 호출방식을 의미
- GET방식이므로 URL로 호출하는 방식인 것
- 이 form의 action을 통해 form안에 있는 <label>등의 내용들이 함께 전달된다.
❓method 속성의 종류
➡️get, post, put, patch, delete
patch는 수정하는 역할(ex. 투두리스트의 할일완료 or 아직 완료 X를 체크)
이는 method의 각기 다른 방식들을 통해 마치 CRUD를 백엔드에서 구현하고 있는 것을 확인 가능
리액트 Todo에 Express 적용
1. Express에 샘플데이터 적용
let todos = [
{
id: 3,
title: "Todo 3",
done: false,
},
{
id: 2,
title: "Todo 2",
done: false,
},
{
id: 1,
title: "Todo 1",
done: false,
},
];
- 샘플데이터
// 다른 router들...
router.patch("/api/todos/:id", function (req, res) {
const id = parseInt(req.params.id);
const todo = todos.find((todo) => todo.id === id);
todo.done = !todo.done;
res.status(200).json(todos);
});
// 다른 router들...
- res.status(200) ➡️ 200번 코드번호를 의미
- res.status(200).json(todos); ➡️자바스크립트코드(todos)를 json으로 변환해서 보내주겠다는 의미
- router.get(”/api/todos/:id”,…)
➡️:id와같은 규칙은 URL이 아닌 값을 보겠다는 의미
➡️localhost:1577/api/todos/2 를 하게되면 2번 id의 데이터가 나오게됨
- const id = parseInt(req.params.id); ➡️정수형으로 변환후 가져옴
- http://localhost:1577/api/todos 로 접속 가능
2. 리액트 Todo에서 Express의 데이터 가져오기
1.리액트 Todo에 통신을 위한 모듈인 axios설치
➡️npm install axios
(package.json의 dependencies에 axios가 추가된 것을 확인 가능)
2. TodoBox컴포넌트의 todoList "데이터 배열"부분 주석처리
- useEffect() Hook을 통해 express서버로부터 값을 가져와서 사용
const TodoBox = () => {
const [todoList, setTodoList] = useState([
// { id: 1, title: "리액트 공부하기" },
// { id: 2, title: "스프링 공부하기" },
// { id: 3, title: "블로그 회고작성" },
]);
useEffect(() => {
}, []);
//...
}
- useEffect안에는 백엔드 서버에서 todoList를 가져오는 함수를 구현
- 비동기를 사용 ➡️ async, await 등을 활용
async 적용
import axios from "axios";
const TodoBox = () => {
//...
useEffect(() => {
async function getTodos(){
axios.get("");
}
}, []);
- axios를 import하고, GET방식을 axios모듈의 get()함수를 통해 구현
await 적용
useEffect(() => {
async function getTodos() {
const result =await axios.get("<http://localhost:1577/api/todos>");
setTodoList(result.data);
}
}, []);
- result에 담기전에 await를 사용하여 서버에로부터 값을 가져오는 것을 기다리도록 함
- setTodoList에 갱신
- 만약 await가 없을 경우 get(URL)로 가라는 요청 후에 바로 result가 담기게되므로 아무 값도 담기지 않는다.
➡️get(URL)요청 후에 값을 가져오는것까지 기다리고 있어야 result에 올바른 값이 담기게된다.
getTodos(); 호출
useEffect(() => {
async function getTodos() {
const result =await axios.get("<http://localhost:1577/api/todos>");
setTodoList(result.data);
}
getTodos();
}, []);
- getTodos()를 통해 다시한번 함수를 호출해주어야 가져온 값으로 동작할 것
(함수를 정의만해놓았으므로 호출을 해주어야함)
네트워크 문제 해결
- 특정 호스트 요청만 허용할 것이라는 설정이 필요
➡️해결방법 : CORS 설정
CORS(Cross-Origin Resource Sharing) 설정 추가
Todo프로젝트의 프론트엔드 서버(localhost:3000)와
Express의 백엔드 서버(localhost:1577)가 다른 포트를 사용하기때문에 차단된 요청을 CORS 설정을 추가하여 해결
1. CORS 모듈 설치
➡️npm install cors
2. Express 서버에 CORS 설정 추가
const cors = require("cors");
const whitelist = ["<http://localhost:3000>", undefined];
const corsOptions = {
origin: function (origin, callback) {
if (whitelist.indexOf(origin) !== -1) {
callback(null, true);
} else {
callback(new Error("Not Allowed Origin!"));
}
},
};
app.use(cors(corsOptions));
- App.js에서 라우터 설정 전에 추가 (var app = express(); 아래에 추가)
- whitelist라는 배열을 관리하는데, 3000번포트의 URL을 허락하고 있음 을 의미
- 여러개의 URL 또한 지정 가능
- Express 서버에서 지정하는 포트는 프론트엔드 포트를 의미
3. Express 서버 열기
- 별도의 Bash로 Express서버를 열어줌
➡️npm start
4. Todo프로젝트의 localhost:3000 확인
- Express 서버의 데이터 (Todo 3, Todo 2, Todo 1)이 잘 가져와진 것을 확인 가능
- “백엔드 서버”와 프론트엔드 서버”가 함께 잘 동작하고 있음을 의미
Todo프로젝트의 값을 추가하거나 수정,삭제하면 express서버에도 값이 추가되도록 구현할 수 있다.
'Recording > 멋쟁이사자처럼 BE 13기' 카테고리의 다른 글
[멋쟁이사자처럼 부트캠프 TIL 회고] BE 13기_32일차_"스프링 프레임워크" (0) | 2025.01.16 |
---|---|
[멋쟁이사자처럼 부트캠프 TIL 회고] BE 13기_31일차_"리액트 useEffect, Memo프로젝트" (1) | 2025.01.15 |
[멋쟁이사자처럼 부트캠프 TIL 회고] BE 13기_30일차_"리액트 Todo" (1) | 2025.01.14 |
[멋쟁이사자처럼 부트캠프 TIL 회고] BE 13기_29일차_"useState, useRef" (0) | 2025.01.13 |
[멋쟁이사자처럼 부트캠프 TIL 회고] BE 13기_28일차_"리액트 React" (1) | 2025.01.10 |