본문 바로가기

개발일지

Node.js 에서 개발 연습

728x90

우선 MariDB 를 다운받아서 설치   https://mariadb.org

Node.js에서 설치된 모듈을 로딩할 때는 require 키워드를 사용한다.

var http = require('http');     // http 모듈을 로드

var mysql = require('mysql');   // mysql 모듈을 로드

 

exports 키워드를 이해하기 위해 다음 사이트 참조

https://uroa.tistory.com/57

 

[Node.js] module.exports 와 exports 이해하기

1. 모듈이란 무엇인가? 모듈이란 관련된 코드들을 하나의 코드 단위로 캡슐화 하는 것을 말합니다. Node.js 에서 예시를 살펴보겠습니다. 다음과 같은 greeting.js 라는 파일이 있습니다. 이 파일은 두개의 함수를..

uroa.tistory.com

아무튼 exports를 사용하여 외부에서 객체를 호출할 수 있도록 한다.

// MariDB 모듈을 사용할 수 있도록 로드하고 접속할 수 있는 정보를 생성

const mysql = require('mysql');

  const conn = {

  host: 'localhost',

  user: 'micro',

  password: 'service',

  database: 'monolithic'

};

상품관리 기능의 서비스를 정의하는 onRequest를 정의

/**
 * 상품 관리의 각 기능별로 분기
*/
exports.onRequest = function (res, method, pathname, params, cb) {

    switch (method) {
        case "POST":  // 등록
            return register(method, pathname, params, (response) => { process.nextTick(cb, res, response); });
        case "GET":   // 조회
            return inquiry(method, pathname, params, (response) => { process.nextTick(cb, res, response); });
        case "DELETE": // 삭제
            return unregister(method, pathname, params, (response) => { process.nextTick(cb, res, response); });
        default:
            return process.nextTick(cb, res, null);
    }
}

상품등록 기능

/**
 * 상품 등록 기능
 * @param method    메서드
 * @param pathname  URI
 * @param params    입력 파라미터
 * @param cb        콜백
 */
function register(method, pathname, params, cb) {
    var response = {
        key: params.key,
        errorcode: 0,
        errormessage: "success"
    };

    if (params.name == null || params.category == null || params.price == null || params.description == null) {
        response.errorcode = 1;
        response.errormessage = "Invalid Parameters";
        cb(response);
    } else {
        // DB 접속 및 처리
        var connection = mysql.createConnection(conn);
        connection.connect();
        connection.query("insert into goods(name, category, price, description) values(? ,? ,? ,?)"
            , [params.name, params.category, params.price, params.description]
            , (error, results, fields) => {
            if (error) {
                response.errorcode = 1;
                response.errormessage = error;               
                }
            cb(response);
        });
        connection.end();
    }
}

상품 조회 기능

/**
 * 상품 조회 기능
 * @param method    메서드
 * @param pathname  URI
 * @param params    입력 파라미터
 * @param cb        콜백
 */
function inquiry(method, pathname, params, cb) {
    var response = {
        key: params.key,
        errorcode: 0,
        errormessage: "success"
    };

    var connection = mysql.createConnection(conn);
    connection.connect();
    connection.query("select * from  goods", (error, results, fields) => {
        if (error || results.length == 0) {
            response.errorcode = 1;
            response.errormessage = error ? error : "no data";
        } else {
            response.results = results;
        }
        cb(response);
    });
    connection.end();
    
}

상품 삭제 기능

/**
 * 상품 삭제 기능
 * @param method    메서드
 * @param pathname  URI
 * @param params    입력 파라미터
 * @param cb        콜백
 */
function unregister(method, pathname, params, cb) {
    var response = {
        key: params.key,
        errorcode: 0,
        errormessage: "success"
    };

    if (params.id == null) {
        response.errorcode = 1;
        response.errormessage = "Invalid Parameters";
        cb(response);
    } else {
        var connection = mysql.createConnection(conn);
        connection.connect();
        connection.query("delete from goods where id = ?"
            , [params.id]
            , (error, results, fields) => {
                if (error) {
                    response.errorcode = 1;
                    response.errormessage = error;
                }
                cb(response);
        });
        connection.end();
    }
}

메인 시작 부분에서 Http 모듈 및 서버생성하고 요청에 부분 처리 부분

const http = require('http');                       
const url = require('url');
const querystring = require('querystring');

// 모듈 소스 로딩
const members = require('./monolithic_members.js');
const goods = require('./monolithic_goods.js');
const purchases = require('./monolithic_purchases.js');

HTTP 서버를 생성하고 요청에 대한 처리

/**
 * HTTP 서버를 생성하고 요청에 대한 처리
 */
var server = http.createServer((req, res) => {         
    var method = req.method;
    var uri = url.parse(req.url, true);
    var pathname = uri.pathname;    
        
    if (method === "POST" || method === "PUT") {
        var body = "";

        req.on('data', function (data) {
            body += data;
        });
        req.on('end', function () {
            var params;
            if (req.headers['content-type'] == "application/json") {
                params = JSON.parse(body);
            } else {
                params = querystring.parse(body);
            }

            onRequest(res, method, pathname, params);
        });
    } else {        
        onRequest(res, method, pathname, uri.query);
    }
}).listen(8000);  

요청에 대해 회원관리 상품관리 구매관리 모듈별로 분기

/**
 * 요청에 대해 회원관리 상품관리 구매관리 모듈별로 분기
 * @param res   response객체
 * @param method    메서드
 * @param pathname  URI
 * @param params    입력 파라미터
 */
function onRequest(res, method, pathname, params) {
    switch (pathname) {
        case "/members":
            members.onRequest(res, method, pathname, params, response);
            break;
        case "/goods":
            goods.onRequest(res, method, pathname, params, response);
            break;
        case "/purchases":
            purchases.onRequest(res, method, pathname, params, response);
            break;
        default:
            res.writeHead(404);
            return res.end();            
    }
}

HTTP 헤더에 JSON형식으로 응답

/**
 * HTTP 헤더에 JSON형식으로 응답
 * @param res   response 객체
 * @param packet    결과 파라미터
 */
function response(res, packet) {
    res.writeHead(200, { 'Content-Type': 'application/json' });
    res.end(JSON.stringify(packet));
}

 

테스트를 하기 위한 소스 부분 

- 모듈 로딩과 옵션 설정 

const http = require('http');

var options = {
    host: "127.0.0.1",
    port: 8000,
    headers: {
        'Content-Type': 'application/json'
    }
};

요청 함수 정의

function request(cb, params) {
    var req = http.request(options, (res) => {      
        var data = "";
        res.on('data', (chunk) => {                 
            data += chunk;
        });

        res.on('end', () => {                       
            console.log(options, data);
            cb();
        });
    });

    if (params) {
        req.write(JSON.stringify(params));
    }

    req.end();
}

상품 관리 API 테스트

호출 순서 goods_post -> goods_get -> goods_delete

function goods(callback) {    
    goods_post(() => {
        goods_get(() => {
            goods_delete(callback);
        });
    });

    function goods_post(cb) {        
        options.method = "POST";
        options.path = "/goods";
        request(cb, {
            name: "test Goods",
            category: "tests",
            price: 1000,
            description: "test"
        });
    }

    function goods_get(cb) {
        options.method = "GET";
        options.path = "/goods";
        request(cb);
    }

    function goods_delete(cb) {
        options.method = "DELETE";
        options.path = "/goods?id=1";
        request(cb);
    }
}

회원 관리 API 테스트

호출순서 members_delete -> members_post -> members_get

function members(callback) {

    members_delete(() => {
        members_post(() => {
            members_get(callback);
        });
    });

    function members_post(cb) {        
        options.method = "POST";
        options.path = "/members";
        request(cb, {
            username: "test_account",
            password: "1234",
            passwordConfirm: "1234"
        });
    }

    function members_get(cb) {
        options.method = "GET";
        options.path = "/members?username=test_account&password=1234";
        request(cb);
    }

    function members_delete(cb) {
        options.method = "DELETE";
        options.path = "/members?username=test_account";
        request(cb);
    }
}

구매 관리 API 테스트

호출순서 

purchases_post -> purchases_get 

function purchases(callback) {

    purchases_post(() => {
        purchases_get(() => {
            callback();
        });
    });

    function purchases_post(cb) {        
        options.method = "POST";
        options.path = "/purchases";        
        request(cb, {
            userid: 1,
            goodsid: 1
        });
    }

    function purchases_get(cb) {
        options.method = "GET";
        options.path = "/purchases?userid=1";        
        request(cb);
    }
}

최종적으로 테스트를 실행

console.log("============================== members ==============================");
members(() => {
    console.log("============================== goods ==============================");
    goods(() => {
        console.log("============================== purchases ==============================");
        purchases(() => {
            console.log("done");
        });
    });
});
728x90