이 포스팅은 자바스크립트 문법을 어느정도 알고 있다는 가정하에 쓰여진 포스팅입니다
만일 자바스크립트 문법을 모르시면 자바스크립트에 대한 공부를 한 후 오시는 것을 추천드립니다
추천) 생활코딩 - Javascript : https://www.opentutorials.org/course/3085
이 튜토리얼을 따라오다 보면 어느 순간 이런 생각이 들 것이라 생각한다. localhost:3000 으로는 접속할 수 있는데 왜 localhost:3000/about과 같은 URL은 못쓰냐고
실제로 우리가 웹서비스들을 이용하다보면 www.service.com 머시기하는 도메인 뒤에 /mypage, /board, /djWjrnwjWJrn 등등 URL 뒤에 이런저런 Path가 주렁주렁 매달려 있는 모습을 쉽게 볼 수 있다.
저것이 바로 엔드포인트(EndPoint)라는 것인데, 엔드포인트란 서버에서 제공하는 서비스를 이용할 수 있도록 서버에서 열어주는 커뮤니케이션 채널의 한쪽 끝 지점을 말하는 것인데...
이렇게 어려운 표현은 이해하기 어려우니 쉽게 이야기 하자면 서버에서 서비스를 이용할 수 있도록 열어주는 일종의 창구라고 볼 수 있다
웹 서비스에서 엔드포인트는 보통 저렇게 URL의 Path 형태로 적어서 요청하는 경우가 많다. 물론 엔드포인트 ≠ Path 이니 오해는 하지 말도록 하자. 엔드포인트를 Path의 형태로 호출하는 것 뿐이다
우선 폴더구조를 좀 정리하도록 하겠다
NodeTutorial
├─ app.js
├─ package-lock.json
├─ package.json
└─ public
├─ .DS_Store
├─ css
│ └─ style.css
├─ html
│ ├─ about.html
│ └─ dog.html
└─ images
└─ Dog.jpg
위와 같이 html 파일들을 public 폴더 내부로 집어넣는 정도의 정리만 했다.
그냥 본인이 보기 편하려고 정리한 것이니 안해도 된다.
우선 app.js 파일을 열어보자
import express from 'express'
import { readFile } from 'fs'
const app = express()
app.use(express.static('public/images'))
app.use(express.static('public/css'))
app.get('/', (req, res) => {
readFile('public/html/dog.html', 'utf-8', (err, data) => {
if(err) { res.send('No Such File or Directory') }
res.send(data)
})
})
app.listen(3000)
일단 모르고 넘어갔지만 app.get의 첫번쨰 파라미터로 주는 문자열에 주목해보자, 그리고 우리가 귀여운 댕댕이들의 사진을 서버에서 불러오기 위해 사용 했던 방법을 한번 떠올려 보자
import express from 'express'
import { readFile } from 'fs'
const app = express()
app.use(express.static('public/images'))
app.use(express.static('public/css'))
app.get('/', (req, res) => {
readFile('public/html/dog.html', 'utf-8', (err, data) => {
if(err) { res.send('No Such File or Directory') }
res.send(data)
})
})
app.get('/Dog', (req, res) => {
readFile('dog.jpg', (err, data) => {
if(err) { res.send('No Such File or Directory') }
res.send(data)
})
})
app.listen(3000)
그 때는 두번째 메서드를 작성할 때 첫번째 인자로 /Dog
이란 문자열을 준 것이 생각날 것이다. 그리고 html 파일에서 img 태그의 src 속성으로 /Dog를 주니 댕댕이들 사진이 불러와 지던 것이 생각날 것이다
바로 app.get 메서드의 첫번째 인자가 엔드포인트 값이다. 첫번째 파라미터로 주는 문자열이 바로 엔드포인트가 된다. 만일 그냥 /
만 적게 되면 아무런 Path도 주지 않았을 때의 처리를 하게 된다. 그러니까 localhost:3000
과 같은 URL로의 접속을 처리한다
함수를 작성할때 예를 들어 첫번째 인자로 /about
을 주게되면 URL 뒤에 /about
이라는 Path를 붙여주게 되면 우리가 localhost:3000/about
으로 접속했을 때 서버가 /about
이란 엔드포인트를 정의한 함수를 찾아서 그 함수에 작성되어 있는 명령을 처리한 후 우리에게 그 결과를 반환하게 된다
자 설명만 듣지 말고 코드로 한 번 타이핑을 해보자
우선아래와 같은 about 페이지를 보여줄 html 파일을 작성하였다. 별 건 없고 그냥 This is /about page 라는 글자만 보여주는 페이지이다
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>about page</title>
</head>
<body>
<h1>This is /about page</h1>
</body>
</html>
다음으로는 서버 코드를 아래와 같이 수정해주자
import express from 'express'
import { readFile } from 'fs'
const app = express()
app.use(express.static('public/images'))
app.use(express.static('public/css'))
app.get('/', (req, res) => {
readFile('public/html/dog.html', 'utf-8', (err, data) => {
if(err) { res.send('No Such File or Directory') }
res.send(data)
})
})
app.get('/about', (req, res) => {
readFile('public/html/about.html', 'utf-8', (err, data) => {
if(err) { res.send('No Such File or Directory') }
res.send(data)
})
})
app.listen(3000)
새로운 app.get을 하나 더 추가하고 첫번째 인자로 /about
을 주었다. 이제 localhost:3000/about
으로 접속하게 되면 서버가 about.html이란 파일을 읽어서 우리에게 보내줄 것이다. 코드를 저장하고 localhost:3000
으로 한번 접속해보자
URL 맨 끝부분에 /about
이라는 Path를 붙여주니 정상적으로 about.html 파일을 불러와서 보여준다
이런 식으로 첫번째 인자로 서로 다른 문자열을 줘서 여러개의 엔드포인트를 생성할 수 있다. 만약 엔드포인트를 더 많이 만들고 싶다면 그냥 아래와 같이 app.get을 여러개 생성해주면 된다
app.get('/ep1', () => { ... } )
app.get('/ep2', () => { ... } )
app.get('/ep3', () => { ... } )
app.get('/ep4', () => { ... } )
app.get('/ep5', () => { ... } )
이러기만 하면 끝이다. 그럼 나중에 서버를 실행시켰을 때 프레임워크가 저 엔드포인트들을 등록하고 저 엔드포인트를 호출하는 요청이 날아올 때 마다 정의해놓은 코드를 실행한다
Express는 이미 정의해놓지 않은 엔드포인트에 대한 예외를 기본적으로 제공하지만 사진과 같이 날아오면 그냥 이상한 외계어가 날아오는 것 처럼 보일 뿐이다
만약 정의하지 않은 엔드포인트에 대해 저런 못알아먹을 소리가 아닌 존재하지 않는 페이지라는 메시지를 보내주고 싶다면 아래와 같이 코드를 넣어주면 된다
app.use((req, res, next) => {
// 여기다 코드 작성
})
req과 res는 지금까지 써오면서 무슨 역할을 하는 객체인지 알겠지만 모르는 개념이 2개나 나왔는데(app.use, NextFunction) 일단은 이런 것도 있구나 하고 넘어가자. 나중에 다 알려주겠다
app.use를 정의하고 그 안에 그냥 콜백함수 하나만을 넣은 코드가 보일 것이다. app.use에 대한 설명은 기회가 되면 나중에 설명하기로 하고, 일단 app.use에 3개의 값을 인자로 받는 콜백함수를 넣으면 된다. 이 중 맨 마지막으로 적혀있는 next는 일종의 콜백인데 여기서는 굳이 쓸 필요가 없으니 넘어가도록 하자
저렇게 정의한 메서드 내부에 만일 존재하지도 않는 페이지로 요청을 보냈을 때 서버가 어떻게 동작하면 되는지에 대한 코드를 작성해 주면 된다
본인은 우선 대충 존재하지 않는 페이지라는 걸 알려주는 html 파일을 하나 만들었다. 본인 취향껏 만들어보자
<!-- notFound.html -->
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>404 Not Found</title>
</head>
<body>
<h1>404 Not Found</h1>
<h1>존재하지 않는 페이지 입니다</h1>
</body>
</html>
코드는 아래와 같이 작성해주었다
// app.js
import express from 'express'
import { readFile } from 'fs'
const app = express()
app.use(express.static('public/images'))
app.use(express.static('public/css'))
app.get('/', (req, res) => {
readFile('public/html/dog.html', 'utf-8', (err, data) => {
if(err) { res.send('No Such File or Directory') }
res.send(data)
})
})
app.get('/about', (req, res) => {
readFile('public/html/about.html', 'utf-8', (err, data) => {
if(err) { res.send('No Such File or Directory') }
res.send(data)
})
})
app.use((req, res, next) => {
readFile('public/html/notFound.html', 'utf-8', (err, data) => {
if(err) { res.status(404).send('404 Not Found') }
res.status(404).send(data)
})
})
app.listen(3000)
이제 서버를 실행하고 정의하지도 않은 아무 엔드포인트나 붙여서 접속해보자
미리 작성해놓은 html파일이 정상적으로 날아온다