Notice
Recent Posts
Recent Comments
Link
«   2025/07   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31
Tags
more
Archives
Today
Total
관리 메뉴

유댕이의 개발공부일지

간단 Node.js(express) 본문

카테고리 없음

간단 Node.js(express)

유댕2 2021. 11. 19. 14:34

NodeJs의 탄생 배경 및 NodeJs란 뭘까?

모든 새로운 학습을 할 때 그 홈페이지에 간단하게 이 기술을 ~ 입니다 라고 간단히 소개를 한다.

노드는 본인을 'node js is a javascript runtime built on Chrome's V8 Javascript Engine' 라고 소개

한다. 하지만 나는 이렇게 한줄로는 느낌이 오질 않다. 아래 내용을 보도록 하겠다.

옛날 html,css와 같은 정적타이핑 언어로 웹사이트를 구성하던 때가 있었다. 하지만 1995년 자바스

크립트가 나오게 되고, 많은 웹브라우저에서 자바스크립트 엔진을 사용하게 되었다.

exploler(chakara Engine), safari(javascript-core-Engine), firefox(spiderMonkey), chrome(V8

Engine)등 각자의 브라우저들마다 각자의 자바스크립트엔진을 만들어 사용하게 된다. 이렇듯 자바스크립트에

대한 활용도가 높아지면서 많은 사람들이 자바스크립트를 배우고 사용하게 되었다. 이때 Ryan이라는 젊은

개발자가(81년생이다.) 열심히 배운 자바스크립트로 뭐든 다 할 수 있다면 얼마나 좋을까란 생각을 하게되어

2009년 세상에 나오게 되었고 nodejs를 아래와 같이 소개한다.

'node js is a javascript runtime built on Chrome's V8 Javascript Engine'

또한 nodejs는 오픈소스이며 크로스플랫폼, 백엔드에서도 사용 가능하며 자바스크립트 런타임환경이다.

즉, 브라우저 밖에서도 자바스크립트 코드로 모든걸 해준다. 지금 나와 같은 주니어 개발자들이 javascript를

학습하면서 심심치 않게 들었던 말인 javascript everywhere 이란말의 근거의 시작이라 볼 수 있다.

Nodejs를 배우는 이유

  1. Javascript로 client-server모두 개발이 가능하다.

이전엔 client에서는 javascript로 server에서는 Java를 활용해서 개발을 많이 진행해왔다. 만약 한 사람이

모든 것을 개발하는데 배워야하는 양이 많으며 혹시 다 아는 사람이 개발을 하더라도 두가지의 프로그래밍 언어를

왔다갔다하며 배우기엔 힘들다. 하지만 Javascript하나만 사용하면 이런 부분에서 헷갈리거나 혼돈이 오지않아

개발 생산성이 높아진다. 또한 프론트엔드 개발자들이 큰 리소스 투자없이 백엔드를 배워보고 경험해 볼 수

있다. 이로인해 어느정도 자신의 분야가아닌 server단에 대한 이해도가 높아짐으로 개발을 하는데 시야가

넓어 질 수 있다.

  1. 50%가 넘는 개발자들이 nodejs를 사용한다.

많은 개발자들이 사용한다는 것은 그만큼 개발 하는데 있어 강력한 커뮤니티가 존재한다는 것이다.

또한 많은 회사에서도 사용을 하다보니 이런 회사에서 증명된 좋은 퀄리티의 코드를 쉽게 접근할 수 있다는 점이다.

위의 두가지가 합쳐지면 또 다른 장점이 나오는데 그것은 우리가 개발하면서 '이런게 있었더라면...'하는 내용은

이미 라이브러리형태로 만들어져 있거나 해결책이 많아 개발하는데 편리하다는 점이 장점이다.

Nodejs 장단점

위의 내용을 보면서 그렇다면 노드를 무조건 써야겠다 라고 생각할 수 있지만 그건 아니다.

상황에따라 어떻게 장단점이 있는지 확인해 보자.

nodejs 장점

  • 멀티 스레드 방식에 비해 쉽고 적은 컴퓨터 자원 사용
  • 웹서버 내장되어 있음
  • Javascript를 사용함
  • Json형식과 쉽게 호환됨

nodejs 단점

  • 싱글스레드라서 CPU코어 하나만 사용
  • 싱글 스레드가 멈추지 않도록 관리가 필요함
  • 서버 규모가 커지면 서버 관리하기 어려움
  • CPU작업이 많은 서버로는 부적합

Node.Js 사용해 보기

위의 내용을 보고 어느정도 node를 사용할 준비가 되었다. 사실상 계속 말했듯 node의 최대 장점은

개인적으로 Javascript를 사용한다는 것이다. 어느정도 javascript에 익숙하면 한번도 node를 공부하

지 않아도 어느정도 코드를보고 이해를 할 수 있고 실제 내가 서버를 실행시키는 것도 쉽게 할 수 있다

let http = require("http")

http.createServer(function (req, res) {

	res.writeHead(200, { 'Content-Type' : 'text/plain' });
	res.end('hello world');
}).listen(Your port number);

console.log('server is running')

Express

express의 공식문서를 가면 본인을 이렇게 소개한다. " Node.js를 위한 빠르고 개방적인 간결한 웹 프레임 워크"

어느정도 노드에대한 이해가 생기고 서버도 한번 실행시켜보았다. 노드의 장점을 공부할 때 우리는 50%가

넘는 개발자가 노드를 사용했던 경험이 있단걸 확인하였다. 또한 많은 사람들이 사용한다는 것의 장점 또한

알고있다. 우리는 node의 framework중에서 express를 활용해 위의 코드를 다시 작성해보자.

const express = require('express')
const app = express();

app.get('/', function (req, res) {
	res.send('Hello World');
});

app.listen(your port number, function() {
	console.log("server is running")
});

Router

익스프레스에서 라우터는 기본적으로 어플리케이션 서버에서 경로를 제어하는 목적을 가진다.

클라이언트에서 서버로 접속할 때는 특정 URL을 통해 접속하고 서버에서는 이 URL에 해당 내용을 클라이언트로 보내준다.

const express = require("express")
const app = express()

app.METHOD("url", function ( req, res ) {
	 res.send("tony")
})

위의 코드와 같이 간단하게 라우터를 사용할 수 있다. app은 익스프레스의 인스턴스라 생각하면 되며 get,post,put, patch, delete등 상황에 맞게 필요한 메서드를 사용하면 된다. 또한 라우터를 사용하면 각각에 필요에 따라 서로 다른 컴퍼넌트를 생성해 모듈화를 시키는데 용이하다.

Library

프로젝트 코드를 보기전 제가 사용했던 라이브러리를 소개하겠다.

나는 nodemon, helmet, cors, morgan을 사용했다. 각각의 라이브러리를 사용한 이유는

  • nodemon

우리가 node를 사용할 때 내용이 바뀌면 계속해서 server를 재실행 시켜야 했었는데 nodemon을 사용하면 계속해서 바뀐내용을 업데이트 해준다.

  • helmet

보안 목적이다. 다양한 http 헤더를 설정해 express앱의 보호를 이 라이브러리 하나로 100%는 아니지만 어느정도 보완해준다.

  • morgan

서버의 상황을 표시해 주는 역할을 한다. 우리가 리덕스를 사용할 때 이런 리덕스 상태변화를 편하게 확인하기 위해 Logger라는 라이브러리를 사용했는데 비슷한 역할이다.

node.js용 http Request를 확인하는 logger이다.

  • cors

CORS ( Cross Origin Resource Sharing ) 의 약자이다. 포트가 다른 서버에서 클라에서 요청을

하면 브라우저가 보안상의 이유로 API를 차단하면서 생기는 에러이다. 이러한 에러를 해결하는데는 Access-Control-Allow-Origin response헤더를 추가해 문제를 해결 할 수 있지만 노드를 사용하면서 계속해서 같은 헤더를 통해서 개발하기는 힘들다.

이러한 문제를 해결해주는게 cors이다.

cors 를 받아 그냥 실행만 시켜주면 이러한 문제를 쉽게 해결할 수 있는 라이브러리이다.

Project Code

이제 노드, 익스프레스 및 익스프레스에서 제공하는 라우터, 라이브러리를 알아보았으니 아래 코드를 보겠다.

// app.js

import express from 'express';
import 'express-async-errors';
import cors from 'cors';
import morgan from 'morgan';
import helmet from 'helmet';
import hmRouter from './router/hm.js';
import fcmRouter from './router/fcm.js';

const app = express();

app.use(express.json());
app.use(helmet());
app.use(cors());
app.use(morgan('tiny'));
app.use('/hm', hmRouter);
app.use('/fcm', fcmRouter);

//not found
app.use((req, res, next) => {
  res.status(404).send('not available');
});

//server 500 error
app.use((error, req, res, next) => {
  console.error(error);
  res.status(500).send('try again plz');
});

app.listen(5000);

app.js는 server를 관리하는 최상단 컴퍼넌트이다. 전체적으로 제가 필요로 하는 라이브러리를 설정해주고 통신에 에러가있을때 공통적으로 처리해야하는 작업을 한다.

// router/fcm.js

import express from 'express';
import admin from 'firebase-admin';
import serviceAccount from '../serviceAccountKey.json';

const router = express.Router();

router.get('/', (req, res, next) => {
  if (!admin.apps.length) {
    admin.initializeApp({
      credential: admin.credential.cert(serviceAccount)
    });
  }

  let fcm_target_token = your token

  let message = {
    notification: {
      title: '이미지 업로드 성공',
      body: 'tony'
    },
    token: fcm_target_token
  };
  admin
    .messaging()
    .send(message)
    .then(function (res) {
      console.log('fcm success', res);
    })
    .catch(function (err) {
      console.log(err);
    });
  return res.send('success');
});

export default router;

파이어 베이스 푸쉬 메세지(fcm) 기능구현을 위한 컴퍼넌트이다.

이부분은 아래의 링크를 참조하자.

Fcm에 대한 블로깅

// router/hm.js

import express from 'express';
import 'express-async-errors';

const router = express.Router();

const aboutProject = {
  title: 'hellomarket mini project',
  subTitle: "van's mission",
  description:
    'chloe, tony hellomarket 주니어들이 1달정도의 시간동안 밴이 주신 미션을 한 결과입니다.'
};

const hmDevMembers = [
  {
    id: '1',
    name: 'van',
    createAt: Date.now().toString(),
    position: 'CTO',
    gender: 'male'
  },
  {
    id: '2',
    name: 'chloe',
    createAt: Date.now().toString(),
    position: 'junior',
    gender: 'female'
  },
  {
    id: '3',
    name: 'tony',
    createAt: Date.now().toString(),
    position: 'junior',
    gender: 'male'
  }
];

//get
router.get('/members', (req, res, next) => {
  res.status(200).json(hmDevMembers);
});

router.get('/intro', (req, res, next) => {
  res.status(200).json(aboutProject);
});

export default router;

해당 컴퍼넌트는 프로젝트에서 어떤 프로젝트인지를 간략히 소개해주는 정적 페이지 구현을 위해 만든 간단한 컴퍼넌트이다.