[데브코스][2-4] 백엔드 기초 + 예시로 서버 페이지 구축

·2024년 4월 19일
0

데브코스

목록 보기
7/20

1. 쇼핑몰 프로젝트 제작

그림 상단 order list 클릭 시 order list.html로 이동

go home 클릭 시 메인 페이지로 이동

메인 하단의 order 클릭 시 order.html로 이동

2. 백엔드

2.1 백엔드의 구조

클라이언트 ↔ 웹 서버



웹 서버는 정적 페이지에 대응

*정적 페이지 - 화면의 내용/데이터 등의 변동이 없는 페이지

*동적 페이지 - 데이터 처리/연산을 통해 화면의 내용, 데이터가 변하는 페이지

웹 어플리케이션 서버는 동적 페이지 처리 진행

필요한 데이터 연산을 위해 데이터베이스와 연결되어 있고, 데이터 조회/수정/삭제에 대한 처리를 요청함

*데이터 베이스 - 데이터를 통합해 효율적으로 관리하기 위한 데이터 집합체를 칭함

3. Node.js

자바스크립트를 스크립트 언어 이상의 프로그래밍 언어 역할이 가능하도록 지원하는 플랫폼

node js를 이용해 자바스크립트로 백엔드 구현 가능

자바스크립트에게 운동장 제공

node js라는 운동장에서 활동할 수 있게 됨

//server.js

let http = require('http'); // http 모듈은 node js가 가진 기존 모듈 중 하나

function onRequest(request, response){
    response.writeHead(200, {'Content-Type' : 'text/html'});
    response.write('Hello.js'); //writebody 요약
    response.end();
}

http.createServer(onRequest).listen(8888);
// localhost:8888
// 우리가 만든 함수로 서버가 일 할건데, 클라이언트가 그걸 받을려면 8888 주파수로 맞춰야 한다

// 클라이언트랑 서버가 대화하려면 주파수가 같아야 함
// 프로토콜 마치 편지 쓸 떄의 형식처럼
// http 프로토콜 템플릿 존재

작성 후 node.js 실행하려면

터미널에서 node 파일명

중단하려면 ctrl + c

3.1 프로토콜


//server.js

function onRequest(request, response){
    response.writeHead(200, {'Content-Type' : 'text/html'});
    response.write('Hello.js');
    response.end();
}

head에는

  1. 통신상태가 어떤지?
    1. 200 - 정상이다
  2. 응답이 어떤 형태인지?
    1. text/html이다.
  3. 내용은 “Hello.js”이다.
  4. 이제 보낼 내용 끝! → response.end();

3.2 모듈화

우리 서버도 모듈처럼 만들기

server.js 파일 외에 index.js 파일 생성 후 다음의 코드 삽입 후 터미널에서 서버 돌리면 작동됨

let http = require('http'); // http 모듈은 node js가 가진 기존 모듈 중 하나

function onRequest(request, response){
    response.writeHead(200, {'Content-Type' : 'text/html'});
    response.write('Hello.js');
    response.end();
 }
    
http.createServer(onRequest).listen(8888);
}
let server = require('./server');

index.js를 통해서 server.js가 실행됨
서버 모듈을 단순히 불러왔다는 사실만으로 켜지면 맘대로 껐다가 켰다가 유연성이 떨어짐

따라서, server.js에서 start 함수 생성 후 안에 기존의 함수 삽입

함수를 부를 때 코드가 실행되도록 하면 됨

let http = require('http'); // http 모듈은 node js가 가진 기존 모듈 중 하나

function start(){
    function onRequest(request, response){
        response.writeHead(200, {'Content-Type' : 'text/html'});
        response.write('Hello.js');
        response.end();
    }
    
    http.createServer(onRequest).listen(8888);
    // localhost:8888
    // 우리가 만든 함수로 서버가 일 할건데, 클라이언트가 그걸 받을려면 8888 주파수로 맞춰야 한다
    
    // 클라이언트랑 서버가 대화하려면 주파수가 같아야 함
    // 프로토콜 마치 편지 쓸 떄의 형식처럼
    // http 프로토콜 템플릿 존재
    
    
}

exports.start = start;
// 바깥에서 start를 사용할 수 있도록 함
// 현재 코드 안의 start 함수를 바깥에서도 사용할 수 있도록 만들어줌
let server = require('./server');
// index.js를 통해서 server.js가 실행됨
// 서버 모듈을 단순히 불러왔다는 사실만으로 켜지면 맘대로 껐다가 
// 켰다가 유연성이 떨어짐

server.start();

이렇게 만들고 작동하면 오류가 발생

  • server.js 파일에서는 전역 변수, 함수만 존재해서 globalThis 객체의 프로퍼티로 저장되고, 다른 모듈에서도 접근 가능 (이게 최상위 스코프니까, exports 작업 없이 require 해도 다른 파일에서도 globalThis 객체를 통해서 server.js파일의 function에 접근 가능)
  • 하지만, index.js 파일의 경우, function onRequest 함수 위에 start 함수가 상위 함수로 추가됨. onRequest 함수는 start의 지역 함수라서 start 함수 내부에서만 접근 가능하고, 다른 모듈에서 직접 onRequest 함수에 접근 불가함. 다른 모듈에서도 사용하려면 module.exports를 통해서 명시적으로 내보내기를 해야 함.
  • 전역 함수랑 변수만 존재하는 파일이더라도 혼란스럽게 전역함수가 남용되는 걸 막기 위해서 exports 작업을 명시적으로 진행해줘야 함→ 모듈 간 의존성 명확히하고 코드 가독성과 유지 보수성 높임

3.3 url(uniform resource locator)

url은 인터넷 상에서 웹 페이지가 어디 있는지 위치를 알려주는 주소.

쉽게 말해서 웹 페이지 주소라고 할 수 있음

http://localhost:8888

로컬호스트: 내 컴퓨터 주소(각자의 컴퓨터가 스스로 로컬 호스트라고 칭함)

//server.js

let http = require('http'); // http 모듈은 node js가 가진 기존 모듈 중 하나

function start(){
    function onRequest(request, response){
		    let pathname = url.parse(request.url).pathname;
		    console.log('pathname : ' + pathname);
    
        response.writeHead(200, {'Content-Type' : 'text/html'});
        response.write('Hello.js');
        response.end();
    };
    
    http.createServer(onRequest).listen(8888);
    
    // localhost:8888
    // 우리가 만든 함수로 서버가 일 할건데, 클라이언트가 그걸 받을려면 8888 주파수로 맞춰야 한다
    
    // 클라이언트랑 서버가 대화하려면 주파수가 같아야 함
    // 프로토콜 마치 편지 쓸 떄의 형식처럼
    // http 프로토콜 템플릿 존재
    
    
}

exports.start = start;
// 바깥에서 start를 사용할 수 있도록 함
// 현재 코드 안의 start 함수를 바깥에서도 사용할 수 있도록 만들어줌

url 모듈은 url을 통해서 입려된 값을 사용할 수 있도록 도와줌

url 모듈 종류 3가지

  • parse() - 문자열 입력 → 객체 생성
  • format() - 객체 입력 → 문자열 생성
  • resolve() → 상대 Url을 절대 url로 변경

3.4 router

어디로 갈지 경로 정해주는 파일

route + er

//router.js

function route(pathname){
	console.log('pathname :' + pathname);
}

exports.route = route;

서버에서 pathname 받아옴

pathname은 서버를 먼저 받아야 하지만

console.log 작업하는 건 route의 역할로 위임

console.log 작업하는 함수 생성 후, 모듈화해서 서버에서 부를 수 있도록 작업

//server.js

let http = require('http'); // http 모듈은 node js가 가진 기존 모듈 중 하나

function start(route){
    function onRequest(request, response){
		    let pathname = url.parse(request.url).pathname;
		    route(pathname);
        response.writeHead(200, {'Content-Type' : 'text/html'});
        response.write('Hello.js');
        response.end() 
    };
    
    http.createServer(onRequest).listen(8888);
    
    // localhost:8888
    // 우리가 만든 함수로 서버가 일 할건데, 클라이언트가 그걸 받을려면 8888 주파수로 맞춰야 한다
    
    // 클라이언트랑 서버가 대화하려면 주파수가 같아야 함
    // 프로토콜 마치 편지 쓸 떄의 형식처럼
    // http 프로토콜 템플릿 존재
    
    
}

exports.start = start;
// 바깥에서 start를 사용할 수 있도록 함
// 현재 코드 안의 start 함수를 바깥에서도 사용할 수 있도록 만들어줌

모듈화된 route 함수를 통해서 console.log 작업을 진행해야 하는데,

server 파일에서 route 데이터 가져올 방법은?

index.js 파일에서 서버 파일로부터의 데이터를 가지고 기동해주는 역할 진행하니까, start에 매개변수로 route 삽입 후 index가 실행하도록 작업

//index.js

let server = require('./server');
let router = require('./router');

server.start(router.route);

3.5 Url에 따라 다른 콘솔 찍기

router가 루트를 분배해서 경로를 지정하면 요청을 처리하는 파일인 requestHandler.js 생성

//requestHandler.js

function main(){
	console.log('main');
}

function login(){
	console.log('login');
}

let handle = {};
handle['/'] = main;
handle['/login'] = login;

exports.handle = handle;
//index.js

let server = require('./server');
let router = require('./router');
let requestHandler = require('./requestHandler');

server.start(router.route, requestHandler.handle);

handle 모듈 소환 후, 서버에 route 모듈과 함께 넘겨줌

//server.js

let http = require('http'); // http 모듈은 node js가 가진 기존 모듈 중 하나

function start(route, handle){
    function onRequest(request, response){
		    let pathname = url.parse(request.url).pathname;
		    route(pathname,handle);
		    
        response.writeHead(200, {'Content-Type' : 'text/html'});
        response.write('Hello.js');
        response.end() 
    };
    
    http.createServer(onRequest).listen(8888);
    
    // localhost:8888
    // 우리가 만든 함수로 서버가 일 할건데, 클라이언트가 그걸 받을려면 8888 주파수로 맞춰야 한다
    
    // 클라이언트랑 서버가 대화하려면 주파수가 같아야 함
    // 프로토콜 마치 편지 쓸 떄의 형식처럼
    // http 프로토콜 템플릿 존재
    
    
}

exports.start = start;
// 바깥에서 start를 사용할 수 있도록 함
// 현재 코드 안의 start 함수를 바깥에서도 사용할 수 있도록 만들어줌

router에서도

//router.js

function route(pathname, handle){
	console.log('pathname :' + pathname);
	
	handle[pathname]();
}

exports.route = route;

http://localhost:8888/main

http://localhost:8888/login

3.6 URL에 따라 프론트엔드에 다른 response 보내기

//requestHandler.js

function main(response){
	console.log('main');
	
			    
  response.writeHead(200, {'Content-Type' : 'text/html'});
  response.write('Main page');
  response.end();
}

function login(response){
	console.log('login');
	
	response.writeHead(200, {'Content-Type' : 'text/html'});
  response.write('Login page');
  response.end();
}

let handle = {};
handle['/'] = main;
handle['/login'] = login;

exports.handle = handle;

각 requestHandler 함수에 response를 처리할 수 있는 기능 추가

//router.js

function route(pathname, handle){
	console.log('pathname :' + pathname);
	if(typeof handle[pathname] === 'function'){
		handle[pathname](response)
	}else {
		response.writeHead(404, {'Content-Type' : 'text/html'});
	  response.write('찾으시는 페이지가 없습니다. ');
	  response.end();
	}
}

exports.route = route;
  1. handle이 객체이고 객체의 프로퍼티 값이 함수(일급객체라서)이니까, 그 값에 대해서 함수처럼 사용 가능 (괄호를 사용해 인자도 넣고)
  2. 만약, 없는 주소 입력하면, 에러 표시 날 수 있도록 하기
    1. 입력된 pathname이 함수 타입이면 그대로 requestHandler에게 전달해서 추가적인 기능 이어나가도록
    2. 하지만, pathname이 함수 타입이 아니라면, requestHandler에 가지 못하고, router 선에서, 오류 페이지 뜨도록 코드 작성
//server.js

let http = require('http'); // http 모듈은 node js가 가진 기존 모듈 중 하나

function start(route, handle){
    function onRequest(request, response){
		    let pathname = url.parse(request.url).pathname;
		    route(pathname,handle);
		    
		    //response.writeHead(200, {'Content-Type' : 'text/html'});
        //response.write('Hello.js');
        //response.end(); 
    };
    
    http.createServer(onRequest).listen(8888);
    
    // localhost:8888
    // 우리가 만든 함수로 서버가 일 할건데, 클라이언트가 그걸 받을려면 8888 주파수로 맞춰야 한다
    
    // 클라이언트랑 서버가 대화하려면 주파수가 같아야 함
    // 프로토콜 마치 편지 쓸 떄의 형식처럼
    // http 프로토콜 템플릿 존재
    
    
}

exports.start = start;
// 바깥에서 start를 사용할 수 있도록 함
// 현재 코드 안의 start 함수를 바깥에서도 사용할 수 있도록 만들어줌

start() 함수의 response 이하 부분을 requestHandler가 작업하도록

//index.js

let server = require('./server');
let router = require('./router');
let requestHandler = require('./requestHandler');

server.start(router.route, requestHandler.handle);

이렇게 없는 경로를 입력하니 Not found 페이지 제작 가능~

(번외) 내 이름으로 된 경로 페이지 제작하기

function main(response){
    console.log('main');

    response.writeHead(200, {'Content-Type' : 'text/html'});
    response.write('Main page');
    response.end(); 
}

function login(response){
    console.log('login');

    response.writeHead(200, {'Content-Type' : 'text/html'});
    response.write('Login page');
    response.end();
}

function Daeun(response){
    console.log('daeun');

    response.writeHead(200, {'Content-Type' : 'text/html'});
    response.write('Daeun Cho');
    response.end();
}

let handle = {}; //key:value 객체
handle['/'] = main;
handle['/login'] = login;
handle['/daeun'] = Daeun;

exports.handle = handle;

function에 Daeun이라는 함수 하나 추가 & handle 객체에도 프로퍼티로 추가하기

http://localhost:8888/daeun

페이지 방문 시 다음의 페이지 확인 가능

0개의 댓글