[개발지식] HTTP / server 기본 원리, 개념
1. HTTP module by node.js
express를 통한 REST API를 사용하기에 앞서,
node.js에서 제공하는 HTTP module을 활용하여 기본적인 server를 구성해본다.
2. server 작동의 기본 원리
2-1. server는 Event를 Listen한다.
기본적으로 server
- server가 아래 정의한 PORT를 통해 client와 server간 응답을 대기한다.
- 응답은 Event로 정의하여 request, response에 대한 처리를 정해줄 수 있다.
- method마다 해당 처리를 해주는 방식이 다른데, 아래와 같은 on method를 사용할 경우엔 socket class type을 활용해서 응답처리를 진행한다.
import http from 'http';
let PORT = 8080;
const server = http.createServer();
server.on('connection', (socket)=>{
console.log('NEW CONNECTION');
})
server.listen(PORT, console.log("SERVER IS RUNNING"));
※ method를 사용하기 위해 server의 EventListener(listen) 이전에 선언하는 것이 좋고, 해당 method에 대한 Event는 기본적으로 최소 2번 발생한다(req, res).
2-2. createServer의 call back function 이용하기
server가 기본적으로 어떻게 작동하고, 응답 및 요청을 받아오는지 이해한다.
- server 작동은 client의 req, server의 res 으로 이루어진다.
- 이러한 인자를 실제로 활용하기 위해선, 이에 부합하는 적절한 method를 활용해야 한다(on method는 socket을 활용하는 것처럼).
- http module을 import 하고, server가 client의 req를 listen(동작)할 PORT를 지정한다.
- node.js에서 제공하는 http module을 사용하므로, 별도의 express는 import하지 않는다.
import http from 'http';
let PORT = 8080;
- http.createServer를 통해 server를 생성한다.
- argument로 req, res인자를 받아오고 client의 request가 req로, server의 response가 res로 저장되어 각각의 data parsing이 가능하다.
- res.writeHead로 content-type을 정의해준다(res.send를 해주면서 자동으로 정의해주기 때문에 별도로 작성할 필요는 없음).
- res.send를 통해 최종적으로 client에게 어떠한 response를 전달할지 정한다(nodejs http module에서는 end만 사용가능하며, express module 사용 시 send까지 사용가능).
const server = http.createServer((req, res) => {
//for header, content-type
res.writeHead(200, { 'Content-Type' : 'text/html'} );
//for web
res.send('<h1>hello world</h1>');
})
server.listen(PORT, console.log("SERVER IS RUNNING"));
※ server는 PORT를 통해 들어오는 client의 request를 listen(응답대기)하며, client로부터 요청이 들어오는 시점에서 listen을 통해 정의한 call-back을 실행한다.
※ response 객체의 method에서 header 정보를 response에 작성하여 client에 전달하는데, status code에 해당하는 response에 담는다.
2-3. 특정 url 요청에 대한 처리
GET / POST 자체적인 개념보다는 url 요청을 분기처리하여 대응할 수 있다.
- 요청이 들어오는 url을 직접 기술하여 처리한다.
const server = http.createServer((req, res) => {
if(req.url == '/'){
res.write('HELLO WORLD');
res.end();
}else if(req.url == '/data'){
res.write(JSON.stringify([1, 2, 3]));
res.end();
}
});
- error handling
const http = require('http');
http.get('localhost:8080/data/api', (res) => {
let data = '';
res.on('data', (chunk) => {
data = data + chunk}
}.on('error', (error) => {
console.log(error)
})
※ 이러한 방법은 hard coding의 일종으로 매우 비효율적, 실무에서 활용하는 방식은 GET/POST method 등을 통해 처리한다(express framwork를 통해).
3. GET / POST
client로부터 들어오는 요청을 정의하는 방식.
- GET/POST는 1차적으로 axios를 활용하여 구현한다.
→ node.js에서 http module을 효율적으로 활용하기 위해 제공하는 라이브러리
→ 이후에 express framework를 활용하여, axios와 비교하였을때 어떤 점에서 더 효율적인지 고민해보도록 한다.
3-1. GET method - query string
GET method
말 그대로 get original resource, 원본이 되는 자원(정보) 및 DB에 접근하고 이를 조회하기 위해 사용한다.
기본적으로 get method는 이미 정해져 있는 DB, server로부터 data를 전달받는 방식이지만, 다른 방법으로 data를 전달하는 방법도 있다.
query string
url 정보를 다룰 수 있는 모듈의 한 종류이다.
url에 적혀있는 문자열은 하나의 규칙을 준수하면서 만들어진 하나의 값이고, query string은 이러한 규칙을 활용하여 데이터를 얻을 수 있도록 한다.
위와 같은 url이 있다고 할때
- query string은 naver 뒤의 ?문자부터 해당하는 부분이다.
- url의 key와 value가 같이 존재하며, where이라는 key, thisPlace라는 value로 해석할 수 있다.
- 동일한 key값에 value가 여러개 존재할 수 있고, 이는 배열로 abc: [where: 'thisPlace', 'thisPlace2'] 처럼 나타낼 수 있다.
3-2. POST - body
resource를 create하기 위한 POST
말 그대로 post resource, 즉 새로운 resource를 create하기 위해 사용한다.
- GET method는 query string 혹은 기존 존재하던 data에만 접근이 가능한 반면, POST method를 사용하면 original data에 새로운 data를 update할 수 있다.
4. js/mjs
commonJS / ES6 module system의 차이
별도의 module system 설정이 없다면 node.js는 default module system으로 commonJS을 사용하며, ECMA module을 지원하는 형식이므로 별도의 설정이 필요하다.
이 module system을 설정하는 방식은 여러가지가 있는데, 그 중 하나가 js/mjs 등의 file 확장자를 이용하는 것이다.
- mjs : ECMA script
- cjs : commonJS
또는 script에서 javascript "type" : "module
을 작성한다면, 해당 project는 ECAM module을 이용한다.
5. 외부 입출력(I/O) 경로를 통한 resource 유입
fs.readFile('');
외부경로를 통해 file 혹은 file 내부의 인터페이스를 보여줄 경우엔 fs module과 해당 method 등을 통해 가져올 수 있다.
const fs = require('fs');
const server = http.createServer((req, res) => {
fs.readFile('./index.html', (err, data) => {
if(err){
throw err;
}else{
res.end(data);
//data to JSON
//JSON.stringify(data)
}
})
※ 외부 I/O를 통해 확보한 data는 buffer에 저장되어 전달
※ data를 외부에서 보이게 하고 싶다면 JSON data로 바꾸거나, JSON.stringify로 전환한다.
5. url 변수를 다루기 위한 유용한 method들
-
array.shift()
→ 배열에서 첫번째 요소를 제거하고, 제거한 요소를 반환한다.
→ shift()를 적용한 후의 array는 대상을 제거한 잔여 요소들이다. -
array.pop()
→ 배열의 마지막 요소를 제거하고, 제거한 요소를 반환한다. -
array.split() or array.split('')
→ 제시된 기준을 바탕으로 배열을 split한다.
→ 공란일 경우 공백, 그 외의 경우엔 기준에 맞추어 문자열 및 배열을 분할한다. -
array.indexOf()
→ String 내에서 기준에 부합하는 문자, 변수가 존재할 경우 해당하는 첫번째 index 값을 반환한다.
→ 존재하지 않는다면 -1을 반환한다. -
Buffer.concat(body).toString();
→ sever에 Event Listen하여 data 존재(전달)할 경우, 임시 저장소(buffer)에 저장한 data를 문자열로 변환하여준다.
→ method는 아니지만 변환 과정을 기억하는 정도는 좋을 것 같다.
6. 참조링크
nodejs에서 제공하는 http method 활용(기본)
https://sukth09.tistory.com/42
node.js query string
https://www.npmjs.com/package/query-string
js/mjs의 차이
https://ui.toast.com/weekly-pick/ko_20190805
https://stackoverflow.com/questions/57492546/what-is-the-difference-between-js-and-mjs-files
res.send는 express에서만 사용할 수 있다.
https://stackoverflow.com/questions/49571642/javascript-node-js-res-send-is-not-a-function-error
content-type와 함께 res.send 이해하기
https://stackoverflow.com/questions/29555290/what-is-the-difference-between-res-end-and-res-send
methods
_indexOf
https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/String/indexOf
_pop (*cf. shift)
https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array/pop
body parsing (chunk, buffer 개념)
https://nodejs.org/ko/docs/guides/anatomy-of-an-http-transaction/
Author And Source
이 문제에 관하여([개발지식] HTTP / server 기본 원리, 개념), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@gyrbs22/WebDevCurriculum-HTTP-module저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)