안녕세계

[SK고용디딤돌] Node.js (5/10) - 6주차 본문

[SK고용디딤돌] Node.js (5/10) - 6주차

Junhong Kim 2016. 8. 10. 18:05
728x90
반응형

- JS는 함수형 언어이므로 함수를 최대한 활용, 가독성을 늘려야 한다.

- 사용자 입력값에 대한 default 설정이 중요


< 파일 복사 프로그램 >

var async = require('async');
var fs = require('fs');
var path = require('path');

var srcPath = (process.argv[2] === undefined) ? path.join(__dirname, process.argv[2]) : __filename;
var destPath = process.argv[3] || (srcPath + '.copy');

// __dirname : 프로그램이 위치한 경로
function readFile(callback) {
var reader = fs.createReadStream(srcPath);
var data = '';
reader.on('data', function(chunk) {
data += chunk;
});
reader.on('end', function() {
console.log('reading completed!!');
callback(null, data);
});
reader.on('error', function() {
callback('reading error occurred!!')
});
}

function writeFile(data, callback) {
var writer = fs.createWriteStream(destPath);
writer.write(data);
callback(null);
}

async.waterfall([readFile, writeFile], function(err) {
if (err) {
console.log(err);
return;
}
console.log('copy completed!!!');
});


< async 연습(1) >

var async = require('async');

function first (callback) {
async.waterfall([
function(cb) {
cb(null, 3 * 6);
},
function(arg1, cb) {
cb(null, arg1 + 2);
},

], function(err, result) {
if (err) return callback('error');
else callback(null, result);
});
}

function second (callback) {
async.waterfall([
function(cb) {
cb(null, 8 * 2);
},
function(arg1, cb) {
cb(null, arg1 / 3);
},
], function(err, result) {
if (err) return callback('error');
else callback(null, result);
});
}

async.parallel([first, second], function(err, results){
if(err) {
console.log(err);
} else {
console.log(results[0] - results[1]);
}
});




var async = require('async');

// 3 * 6
function first(callback1) {
var result = 3 * 6;
callback1(null, result);
}

// 3 * 6 + 2
function second(data, callback2) {
var result = data + 2 ;
callback2(null, result);
}

// 8 * 2 / 3
function third(data, callback3) {
var result = 8 * 2 / 3;
callback3(null, data - result);
}

async.waterfall([first, second, third], function(err, results) {
if(err) {
console.log(err);
} else {
console.log(results);
}
});



- series 직렬 수행, 결과 값을 저장

- parallel 병행 수행

- waterfall 결과 값을 다음 task로 사용.




async waterfall 이나 series 같은 기능을 구현할 수 있다.

가독성이 좋아진다 는 장점

promise를 사용하기위해서는 ECMAScript6를 사용해야함

< promise (async waterfall 의 성능을 같음) vs  async (asyncsms parallel 이라는 강력한 기능을 사용 가능 >


/**
* Created by Tacademy on 2016-08-10.
*/
// promise : 미래에 실행 될 코드를 등록하는 promise함수의 객체
// resolve : 약속이 해결되었을 때
// reject : 약속이 실패했을 때
var async = require('async');
var fs = require('fs');
var path = require('path');

var srcPath = (process.argv[2] !== undefined) ? path.join(__dirname, process.argv[2]) : __filename;
var destPath = process.argv[3] || (srcPath + '.copy');

function readFile() {
return new Promise(function(resolve, reject) {
var reader = fs.createReadStream(srcPath);
var data = '';

reader.on('data', function(chunk) {
data += chunk;
});

reader.on('end', function() {
resolve(data); // then 1번째
});

reader.on('error', function() {
reject('readable stream error...'); // then 2번째
});
});
}
// 미래 실행될 코드를 등록해논 것, 성공하면 resolve. 가져야할 value는 데이터이다.
function writeFile(value) {
return new Promise(function(resolve, reject) {
var writer = fs.createWriteStream(destPath);
writer.on('finish', function() {
resolve('copy completed!!!');
});
writer.on('error', function() {
reject('writer stream error...');
});
writer.write(value);
writer.end(); // flushing... all &
});
}

// promise객체는 내부적으로 실행을 하려면 then 이라는 함수를 호출하게끔 되어있다.
// then에는 함수의 매개변수로 두개의 함수를 받는다.
// resolve함수의 결과값은 첫번째 함수의 value값으로 넘어간다, 성공했을 때
// reject함수의 결과값은 두번째 함수의 reason값으로 넘거간다, 실패했을때

/*
promise.then(function(value) {
console.log(value.toString());
}, function(reason) {
console.log(reason);
});*/

/*
promise.then(function(value) {
console.log(value.toString());
}).then(null, function (reason) {
console.log(reason);
})*/

readFile().then(writeFile)
.then(function(value) {
console.log(value);
})
.catch(function(reason) { // error 오면 잡음
console.log(reason);
});

< contact.json - promise >

/**
* Created by Tacademy on 2016-08-10.
*/
var fs = require('fs');
var path = require('path');

function readFile() {
return new Promise(function(resolve, reject) {
var reader = fs.createReadStream(path.join(__dirname, '/contact.json'));
var data = '';

reader.on('data', function(chunk) {
data += chunk;
});

reader.on('end', function() {
resolve(data);
});

reader.on('error', function() {
reject('readable stream error...'); // then 2번째
});
});
}
function parseToJSON(value) {
return new Promise(function(resolve) {
resolve(JSON.parse(value));
});
}
function printName(value) {
console.log('이름 :', value['name']);
return value;
}

function printAge(value) {
console.log('나이 :', value['age']);
return value;
}
function printGender(value) {
console.log('성별 :', value['gender']);
return value;
}

function printPhone(value) {
console.log('전화 :', value['phone']);
return value;
}
readFile().then(parseToJSON) // then에 들어온 인자가 함수면 return 값을 인자로 만듬, then에 들어가면 promise 객체가 됨
.then(printName)
.then(printAge)
.then(printGender)
.then(printPhone)
.catch(function(reason) { // error 오면 잡음
console.log(reason);
});


1) 제이슨 표기법, 표준

2) osi 7 layer 의 tcp/ip 4layer 관계


conten-type 내가 보내는것의 타입을 정의하는 것임 -> postㅇ



< REST서비스 >

- Code On Demand : 실행 가능한 코드 전송으로 기능 확장

- 정적리소스는 파일로 존재한다. (a.jpg, 1.html 등)

- 동적리소스는 요청에의해서 동적으로 생성되는 리소스

- 이것을 APP과 연결하는 것을 REST API라고하고 이를 각각 URI 또는 URL이라고 한다


''Method : Http Verb''

C : 리소스 생성하려면 POST

R : 리소스 읽으려면 GET

U : 리소스 변경하려면 PUT

D : 리소스 제거하려면 DELETE


GET http://www.example.com/articles?pageNo=1&count=10 기사목록

GET http://www.example.com/articles/1234 기사조회

                                                      ㄴ resource (복수형으로 표현, colletions라고도 함)

POST http://www.exampale.com/aricles 기사입력

PUT   http://www.exampale.com/articles/1234 기사 변경

delet  http://www.exampale.com/articles/1234 기사 삭제

http://host/collections/[{id}][?param=value]

1234 -> 리소스 ID(=컬렉션 ID)



*family photo 서비스

특정연도, 특정사용자가만든 포토를 서비스하려고한다. 여기에 적절한 url을



CRUD + L


* 특정 사용자 정보는 세션에 존재(URL에 표시X)

[GET] http:// ~ /familyphots 모든 사용자의 모든 family photo가 목록 조회

★(세션인증필요)[POST] http:// ~ /familyphotos '특정 사용자'의 '특정년도'의 '가족사진' 생성

[GET] http:// ~ /familyphotos?year=2015 특정사용자의 특정년도(2015년)의 가족사진 목록

[GET] http:// ~ /familyphotos/1111 특정사진(아이디) 조회

★(세션인증필요)[PUT] http:// ~ /familyphotos/1111 특정사진 변경

★(세션인증필요)[DELETE] http:// ~ /familyphotos/1111 특정사진 삭제

[GET] http:// ~ / familyphotos?userid=test@example.com 특정 사용자의 가족사진 목록 조회

★(세션인증필요)[GET]  http:// ~ /profiles/me 특정 자신의 프로필 보기


get/collections -> 목록


[GET] http:// ~ /familyphotos/me 내 가족 사진

me와 같은 식별자를 동적 라우팅 파라미터라고한다.

세션 정보를 읽어서 그 아이디에 대한 db를 얻어서본다-> 동적 라우팅 파라미터


※ 필터를 제외한 URL이 공통된 부분을 하나로 합친다.


동적 라우팅 파라미터는 {}이렇게 표현한다.

node.js에서는 :param이라고한다 -> 이걸할 줄 알아야 프로토콜 정의서를 만들 수 있다.




포토 목록 [GET] http://www.example.com/familyphotos?yyyy=2105&user=chun&count=10&pageNo=1

포토 생성 [POST] http://www.example.com/familyphotos

포토 조회 [GET] http://www.example.com/familyphotos?yyyy=2015&user=chun

포토 변경 [PUT] http://www.example.com/familyphotos?yyyy=2015&user=chun

포토 삭제 [DELETE] http://www.example.com/familyphotos?yyyy=2015&user=chun



728x90
반응형
Comments