express란 node와 javascript를 이용해 웹 서버를 만드는 하나의 프레임워크이다. npm i express를 통해 다운받을 수 있다.
프레임워크와 라이브러리의 차이에 관한 설명이 있었다. 간단히 말하면 필요한 기능들이 도서관에 쫙 깔려있고 사용자가 원할 때 그 기능을 갖다 쓰는 것이 라이브러리이고 짜여진 틀에 따라 우리의 콘텐츠를 끼워넣는 것이 프레임워크란다. 이용자의 자유도에 따른 차이가 큰 듯.
express는 req를 읽는 서버를 만들고, 유저의 http request를 우리가 읽기 좋게 Parsing해주고, 우리가 만든 서버의 response를 예쁘게 만들어 Send하고 render하게 해준다.
🌱 EXPRESS APP : REQ, RES
express로 웹서버를 실행하고자 할 때 가장 먼저 해야할 것은 우리의 index.js 파일의 맨 위에 다음과 같은 코드를 치는 일이다.
var express = require('express')
var app = express()
app.get('/', function (req, res) {
res.send('hello world')
})
app.listen(3000)
express에서의 app이란 브라우저의 window, node에서의 process같은 global object를 의미한다. express가 가진 대부분의 main property와 method들은 app 안에서 정의된다.
위 코드의 마지막줄 app.listen(3000)은 3000번의 포트 번호에서 유저의 req를 듣겠다는 뜻이다. 유저가 port num 3000으로 무언가 url을 입력하면(req), express는 서버에 저장된 일련의 행위를 하여 유저에게 res를 보내는 구조이다.
app.get부분을 보도록 하자. https://localhost:3000/ 이라는 곳으로 들어가면 유저는 '/'의 주소에 send request를 보낸 것과 같다(send가 무엇인진 나중에 배운다). 그러면 app의 2번째 argument로 있는 콜백 함수가 실행되게 된다. 콜백 함수에는 두 개의 파라미터가 있는데, 하나는 req, 다른 하나는 res이다. req(=require)은 유저가 request를 보낸 것에 관한 정보가 담겨있고, res(=response)는 서버에서 유저에게 보내는 res에 관한 정보가 담겨있다. express가 친절하게도 우리를 위해 두 개의 오브젝트를 만들어주었다는 뜻이다. res.send('hello world')는 서버의 response로 'hello world'라는 string을 보내겠다는 뜻이다.
이제 유저가 브라우저를 통해 https://localhost:3000/ 로 진짜! 들어가면 빈 화면에 hello world라고 적힌 글씨를 마주하게 된다. 우리의 response가 잘 send됨을 확인할 수 있다.
참고로 res.send()안에 object를 보내면 자동으로 json파일로 파싱이 되고, html string을 보내면 자동으로 html으로 파싱된다.
🌱 ROUTING
라우팅 패턴이라는 것이 있다.
// routing pattern!!
app.get("/r/:subreddit", (req, res) => {
// r 이후에 오는 모든것들에 대한 처리
// req.params = { subreddit : '우리의 req Input' }
res.send(`<h1>welcome to ${req.params.subreddit}</h1>`);
});
app.get("/r/:subreddit/:postID", (req, res) => {
// 두 개 이상의 params도 처리 가능!
// req.params = { subreddit : '우리의 req Input', postID : '우리의 req input2' }
const { subreddit, postID } = req.params;
res.send(`<h1>welcome to ${subreddit}, ${postID}</h1>`);
});
(수업들으면서 부랴부랴 필기함;)
/r/:subreddit부분을 보자. colon이 붙어있음을 확인할 수 있다. /r/뒤에 들어오는 모든 string을 req.params 안에 집어넣겠다는 뜻이다. 우리가 서버에 https://localhost:3000/r/buchu 를 통한 send request를 보냈다고 가정해보자.
req 오브젝트 안의 param object를 보면 param : { subreddit : buchu } 로 되어있음을 확인할 수 있다. 그래서 req.params.subreddit을 send하면 'welcom to buchu' 라는 h1 tag가 결과값으로 나타나게 된다. 아래 예시에서 두 개 이상의 parameter도 처리할 수 있음을 확인할 수 있다!
🌱 QUERY STRING
유튜브에 무언가를 검색했다고 생각해보자. 나는 요즘 내 친구가 빠져있는 아이돌 더보이즈의 주연이라는 친구를 유튜브에 검색했다.
url 창을 확인해보면, youtube.com/results?search_query=더보이즈+주연 이라는 query string이 있음을 확인할 수 있다!
// request에는 query라는 property존재.
app.get("/search", (req, res) => {
const { q } = req.query;
res.send(`you searched ${q}`);
});
내 index.js파일에 위와 같은 코드를 추가했다. 이제 "https://localhost:3000/search?q=주연" 이라는 url을 통해 request를 했다고 가정하자. 위의 routing에서는 req.params의 object 항목에 무언가가 추가됐다고 한다면, 여기 query string에선 req.query 오브젝트 항목에 무언가가 추가된 것이라고 알면 된다. req.query = { q : "주연" } 으로 된다는 것이다!
참고로 여러 개의 쿼리에선 &을 이용해 구분한다. ?q="주연"&age=26 이면 req.query = { q : "주연", age : 26 }이 되는 것이다.
+) NODEMON
js파일을 수정할 때마다 node를 종료하고 켜는 것이 귀찮으면 nodemon이라는 npm package를 사용할 수 있다. 모듈 다운받은 후 nodemon index.js 커맨드를 입력하면 내가 서버 파일을 수정할 때마다 nodemon이 자동으로 서버를 재시작해주게 된다.
🌱 TEMPLATING
이건 오늘 한거니까 내일 정리할래..