🌿 Node

노드 이해하기2

ji-hyun 2022. 2. 13. 19:20

REST API (Representational State Transfer)

서버의 자원을 정의하고 자원에 대한 주소를 지정하는 방법

  • /user 이면 사용자 정보에 관한 정보를 요청하는 것
  • /post 면 게시글에 관련된 자원을 요청하는 것

 

 

 

 

 

HTTP 요청 메서드

: GET, POST, PUT, PATCH, DELETE

 

 

 

 

 

 

 

 

HTTP 프로토콜

  • 클라이언트가 누구든 서버와 HTTP 프로토콜로 소통 가능
  • iOS, 안드로이트, 웹이 모두 같은 주소로 요청을 보낼 수 있음
  • 서버와 클라이언트 분리

 

 

 

 

 

 

 

 

RESTful

REST API 를 사용한 주소 체계를 이용하는 서버

GET /user 는 사용자를 조회하는 요청, POST /user 는 사용자를 등록하는 요청

 

래스트풀하다~~~~

 

 

 

 

 

 

 

 

 

 

 

다음과 같이 작성해보자.

 

 

 

 

 

네트워크탭 -> Headers

Status Code : 200 ok

 

이어서

Response Header 를 보면

Content-Type 이 적어준 그대로 쓰여짐을 확인할 수 있다.

 

 

 

참고로 Response Header 는 "데이터에 대한 데이터" 라고 이해하면 쉽다... 메타데이터!!!!!!

메타데이터가 이거구만...

 

 

 

 

 

 

 

 

 

REST 서버 만들기

GtiHub 저장소(https://github.com.zerocho/nodejsbook) ch4 소스 참조

restServer.js 에 주목

GET 메서드에서 /, /about 요청 주소는 페이지를 요청하는 것이므로 HTML 파일을 읽어서

전송합니다.

AJAX 요청을 처리하는 /users 에서는 users 데이터를 전송합니다. 

JSON 형식으로 보내기 위해 JSON stringify 를 해주었습니다.

 

그 외의 GET 요청은 CSS 나 JS 파일을 요청하는 것이므로 찾아서 보내주고, 없다면 404 NOT FOUND

에러를 응답합니다.

 

POST나 PUT 메서드는 클라이언트로부터 데이터를 받으므로 특별한 처리가 필요합니다.

res.on('data', 콜백) 과 req.on('end', 콜백) 부분인데요.

3.6.2 절의 버퍼와 스트림에서 배웠던 readStream 입니다. readStream 으로 요청과 같이 들어오는

요청 본문을 받을 수 있습니다. 단, 문자열이므로 JSON 으로 만드는 JSON.parse 과정이 한번 더 

필요합니다.

 

DELETE 메서드로 요청이 오면 주소에 들어 있는 키에 해당하는 사용자를 제거합니다.

해당하는 주소가 없을 경우 404 NOT FOUND 에러를 응답합니다.

 

 

 

 

 

 


요청 처리 설정

server.on('request', doRequest);

 

http.Server 개체에는 다양한 이벤트가 준비되어 있으며, 그 처리를 통합하는 방법도 준비되어 있다. "on"이라는 메소드는 지정된 이벤트 처리를 통합하는 것으로, 첫번째 인수에 이벤트 이름을, 두번째 인수에 통합 처리(함수)를 각각 지정한다.

여기에서는 "request"라는 이벤트에 "doRequest"라는 함수를 할당한다. request라는 것은 http.Server 객체가 클라이언트의 요청을 받았을 때 발생하는 이벤트로, 이를테면 여기에 "브라우저에서 서버에 액세스할 때 서버 응답 처리"를 포함한다.



 

 

var server = http.createServer();
// http 오브젝트의 createServer 메서드를 호출하여 http.Server 개체를 만든다.
// 이것이 Node.js 의 "서버" 가 되는 부분이다.


http.createServer(function(xx){
	// 필요한 처리...
    }).listen(xx);
    
    // createServer 인수에 서버에서 요청을 받았을 때의 처리하는 함수를 작성한다.
    // 그리고 이 후에 listen 이라는 대기하기 위한 메소드도 계쏙 작성되고 있다.
    
    

// 대기 시작
ser.listen(1234);
/*
http.Server 개체의 준비가 되면 listen 메소드를 실행한다.
그러면 서버는 대기 상태가 되고, 클라이언트에서 요청이 있으면 그것을 받아 처리할 수 있다.
인수는 포트 번호를 지정하고 있다.
두번째 인수로서 호스트 이름을 지정하거나, 세번째 인수에 백로그를 지정하거나, 네번째 인수에 콜백함수를
제공할 수도 있다.
*/

 

 

// 헤더 정보 내보내기
res.wrtieHead(200, {'Content-Type': 'text/plain'});
/*
writeHead 는 response 객체의 메소드에서 헤더 정보를 응답에 작성해서 내보내는 것이다.
첫번째 인자는 상태 코드를 지정하고 두번째 인수에 헤더 정보를 연관 배열로 정리한 것이다.
*/

// 컨텐츠 내보내기
res.write('Hello world\n');
/*
HTTP 에는 헤더 정보의 다음에 바디 부분이 되는 콘텐츠를 작성하고 있는데,
이 내용 내보내기를 하고 있는 것이 response 객체의 "wrtie" 이다.
인수에 지정한 값이 바디 부분의 컨텐츠로 작성된다.
이 write 는 여러번 호출할 수 있다. 이것을 호출하여 작성을 하더라도, 아직 콘텐츠는 
종료하지 않으므로, 계속해서 write 으로 추가 작성할 수 있다.
*/

// 컨텐츠 출력 완료(응답 종료)
res.end();
/*
내용 내보내기가 완료되면 마지막으로 response 의 "end" 를 호출하여 콘텐츠 출력을 완료한다.
여기에서는 단지 end 를 호출하고 있을 뿐이지만, 인수로 내보낼 내용의 값을 지정할 수 있다.
그러면 인수의 값을 쓴 후에 내용을 완료한다.
이 end 로 인해 응답 처리는 종료되고, 그 요청의 처리가 완료된다.
"writeHead", "write", "end" 의 3개가 있으면, 클라이언트에 반환 내용은 모두 쓸 수 있다.
*/

 

 

 

 

 

파일을 로드하는 fs 객체

response의 write로 내보낸다고 하더라도, 설마 write으로 HTML 코드를 모두 써내려가야만 하는가? 라고 생각한 사람이 있을 것이다. 그대로 표시하는 Web 페이지의 내용을 스크립트에서 문자열로 준비해야 한다면, 이는 있을 수 없는 일이다.

아무래도 표시할 페이지의 내용은 HTML 파일로 준비하고, 그것을 읽어 표시할 수 있도록 되어 있지 않으면 Web 아니다. 그럼, 여기에서는 이에 대해서 설명하겠다.

 

 

 

 

 

파일 로드는 "fs" 라는 객체로 사용할 수 있으며, require 함수에서 "fs" 를 읽고, 그 안에 있는 메소드를 호출하여

로드한다.

 

// fs 객체 가져오기
var fs = require('fs');
// -> fs 객체도 마찬가지로 읽어 변수에 할당해야 한다.



// 파일 가져오기
fs.readFile(파일의 경로, 인코딩, 콜백함수);
/*
파일을 로드한다. 보통으로 생각하면 "readFile에서 읽은 데이터를 반환"이라고 상상하지만, 다르다. 
readFile는 반환 값이 없다. 왜냐하면 이것은 비동기적으로 실행되는 처리기 때문이다.
파일을 읽는 것은 시간이 걸리는 처리이다. 
따라서 로딩이 끝나면 데이터를 반환하고 나서 진행이 된다면, 경우에 따라서는 매우 오래 기다리게 된다. 
서버에서 그런 일을 하면 이전에 액세스한 사람의 파일을 로드가 완료까지 모두 기다리고 있어야 한다는 것이 된다.
그래서 읽기 시작하면 바로 다음 작업으로 진행하도록 설계가 되어 있는 것이다. 
읽기 작업은 백그라운드에서 이루어 진다. 
그리고 로드가 완료되면 미리 설정해둔 처리를 호출하고, 
"읽기 후의 처리"를 진행시킨다는 개념이다. 
이 "작업이 끝나면 나중에 호출되는 함수"를 "callback 함수"라고 한다.
readFile에는 첫번째 인수에 가져올 파일의 경로를 지정하고, 
두 번째 인수로 인코딩 이름, 
그리고 세번재 인수에 로드 완료 후 콜백 함수를 지정한다. 
로드 작업이 끝나면, 콜백 함수에서 처리를 하도록 하는 것이다.
*/

 

 



출처: https://araikuma.tistory.com/453 [프로그램 개발 지식 공유]

 


// 노드로 http 서버 만들기
const http = require('http');

const server = http.createServer((req, res)=> {
    res.write('<h1>Hello Node!</h1>');
    res.end('<p>안녕</p>')
})

    .listen(8080); // 포트 8080에 프로세스로 올려줌

server.on('listening', ()=>{
    console.log('8080번 포트에서 서버 대기 중입니다.');
})

server.on('error', (error)=>{
    console.error(error);
})

 

 

 

 

 


예외 처리

예외: 처리하지 못한 에러

  • 노드 스레드를 멈춤
  • 노드는 기본적으로 싱글 스레드라 스레드가 멈춘다는 것은 프로세스가 멈추는 것
  • 에러 처리는 필수

 

 

에러가 발생할 만한 곳을 try catch 로 감싼다.

 

 

 

 

throw

"예외" 란 무언가 예외적인 상황이나 에러가 발생했음으로 가리키는 신호입니다.

예외를 "발생시키다(throw)" 라는 것은 그런 에러나 예외 상황을 알린다는 것이다.

 

한편 예외를 "잡아내다(catch)" 라는 것은 그것을 처리한다는 뜻이다.

(즉 그 예외에서 회복하기 위해 무언가 필요하거나 적절한 행동을 취한다는 뜻이다.)

 

 

 

 

 

 

throw 표현식;

->

'표현식' 의 결과값 타입은 무엇이든 될 수 있습니다.

하지만 대부분의 그 타입은 Error 객체 또는 Error 의 하위 클래스 중 하나의 인스턴스가 되곤 한다.

 

 

때로는 에러 메시지를 담고 있는 문자열이나 어떤 에러 코드를 나타내는 숫자 값도 유용할 수 있다.

 

 

 

try 절은 그저 처리할 예외가 발생할지도 모를 코드 블럭을 정의하는 역할을 한다.

try 블록 다음에는 catch 절이 이어진다.

 

catch 절은 try 블록 내부에서 예외가 발생할 경우 호출되는 문장 블록이다.

 

 

catch 절 다음에는 finally 블록이 이어지는데, 여기에는 앞서 try 블록에서 일어난 일에 관계없이 항상 실행이 보장되어야 할 뒷정리용 코드가 포함된다.

 

 

 

catch 나 finally 블록은 생략할 수 있다.... 하지만 try 블록은 catch 나 finally 중 적어도 하나 이상의 블록과 함께 사용되어야만

한다.

 

try { 
/** 
* 정상이라면 이 코드는 아무런 문제없이 블록의 시작부터 끝까지 실행된다. 
* 하지만 경우에 따라 예외가 발생할 수 있다. 
* 예외는 throw 문에 의해 직접적으로 발생할 수도 있고, 
* 또는 예외를 발생시키는 메서드의 호출에 의해 발생할 수도 있다. 
*/ 
} catch (e) { 
/** 
* 이 블록 내부의 문장들은 오직 try 블록에서 예외가 발생할 경우에만 실행된다. 
* 이 문장들에선 지역 변수 e를 사용하여 Error 객체 또는 앞에서 던진 다른 값을 참조할 수 있다. 
* 이 블록에서는 어떻게든 그 예외를 처리할 수도 있고, 
* 그냥 아무것도 하지 않고 예외를 무시할 수도 있고, 
* 아니면 throw 를 사용해서 예외를 다시 발생시킬 수도 있다. 
*/ 
} finally { 
/** 
* 이 블록에는 try 블록에서 일어난 일에 관계없이 무조건 실행될 코드가 위치한다. 
* 이 코드는 try 블록이 어떻게든 종료되면 실행된다. 
* try 블록이 종료되는 상황은 다음과 같다. 
* 1) 정상적으로 블록의 끝에 도달했을 때 
* 2) break, continue 또는 return 문에 의해서 
* 3) 예외가 발생했지만 catch 절에서 처리했을 때 
* 4) 예외가 발생했고 그것이 잡히지 않은 채 퍼져나갈 때 
*/ 
}

 

 

 

 

 

try { 
	// 사용자에게 번호 입력을 요청 
    var n = prompt("정수를 입력해 주세요."); 
    
    // 사용자의 입력이 유효하다고 가정하고 그 숫자의 계승(factorial)을 계산한다. 
    var f = factorial(n); 
    
    // 결과를 표시한다. 
    console.log(n + "! = " + f); 
    } catch (ex) { // 만약 사용자의 입력이 유효하지 않다면 이곳에 도달한다.
    
    // 사용자에게 에러가 무엇인지 알린다. 
    alert(ex);
    }

 

 

 

 

 

 

 

https://webclub.tistory.com/71

 

예외 처리 - throw 및 try/catch/finally

throw & try/catch/finally(Exception Handling) 이 글에서는 예외 처리 방식에 대해 알아봅니다. 프로그램이 실행되는 동안 문제가 발생하면 프로그램이 자동으로 중단됩니다. 이럴 경우에 프로그램이 대처

webclub.tistory.com

 

 

 

 

 

 

 

 

 

 

 

 

setIntercal(()=>{
	console.log('시작');
    try {
    	throw new Error('서버를 고장내주마');
    } catch(err){
    	console.error(err);
    }
}, 1000);

 

try 에서 에러가 발생했지만 throw 해준 것을 catch 에서 받아서 에러가 아닌 것처럼 처리해준다.

 

 

 

 

 

 

 

프로미스의 에러는 따로 처리하지 않으면 어떻게 될까

 

const fs = require('fs').promises;

 

promise 에서 catch 안 써도된다.

대신 콘솔에서 경고가 길게 뜬다.

 

 

이렇게..

 

 

 

 

UnhandledPromiseRejectionWarning

이 문구는 기억하자.

promise 를 썼는데 catch 를 안썼다는 문구...

 

 

노드 버전을 올리면 나중에 문제가 발생할 수 있으니까 catch 문 꼭 작성해주자!!!!!

 

 

 

 

 


// 노드로 http 서버 만들기
const http = require('http');

const server = http.createServer((req, res)=> {
    res.write('<h1>Hello Node!</h1>');
    res.end('<p>안녕</p>')
})

    .listen(8080); // 포트 8080에 프로세스로 올려줌



    const server1 = http.createServer((req, res)=> {
        res.write('<h1>Hello Node!</h1>');
        res.end('<p>안녕</p>')
    })
    
        .listen(8081); // 포트 8081에 프로세스로 올려줌

 

이렇게 동시에 두 개의 서버를 실행할 수도 있다.

 

 

 

 

 

 

 

 

 

 

fs 로 HTML 읽어 제공하기

 

 

1)

 

const http = require('http');
const fs = require('fs').promise;

const server = http.createServer(async (req:Request, res:Response)=> {
    res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8'});
    const data = await fs.readFile('./server2.html');
    res.end(data);
})
    .listen(8080); // 포트 8080에 프로세스로 올려줌

 

 

 

 

 

 

2) try-catch 문으로 에러 처리해주기

 

const http = require('http');
const fs = require('fs').promise;

const server = http.createServer(async (req:Request, res:Response)=> {
    try {
        res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8'});
        const data = await fs.readFile('./server2.html');
        res.end(data);
    } catch(error){
        console.error(error);
        res.writeHead(200, { 'Content-Type': 'text/plain; charset=utf-8'});
        res.end(err.message);
    }
})
    .listen(8080); // 포트 8080에 프로세스로 올려줌

 

 

 

 

 

 

 


JSON.parse()란?

  • parse 메소드는 string 객체를 json 객체로 변환시켜줍니다.

 

 

JSON.stringify란?

  • stringify 메소드는 json 객체를 String 객체로 변환시켜 줍니다.

 

 

 

 

 

var data = {

        Name: "SooYoung"

        , Age: "27"

    }



    var person = JSON.stringify(data);

    var oPerson = JSON.parse(person);



    //output

    alert(person);

    /* Output: "{"Name":"SooYoung","Age":"29"}" */

    alert(oPerson);

    /* Output: Object */

 

 

 

 

https://ithub.tistory.com/54

 

Javascript JSON.parse(), JSON.stringify() 사용하는법

안녕하세요. 오늘은 자바스크립트의 메소드인 JSON.parse()와 JSON.stringify()에 대해 알아보겠습니다. JSON.parse()란? parse 메소드는 string 객체를 json 객체로 변환시켜줍니다. JSON.stringify란? stringify..

ithub.tistory.com

 

 

 

 

 

 

 

 

 

 

JSON은 네트워크 데이터 전송방식의

표준 Format으로 사용되고 있습니다.

(이외에는 xml, html)

Json은 String 문자열이므로

실제 자바스크립트에서 사용하기 위해서는 

파싱을 하여 객체로 사용할 수 있는데요.

 

자바스크립트에서 

이럴때 사용하는 객체가

JSON 객체입니다.

JSON객체에는 parse와 stringify가

내장되어 있어서

String - > Object로

Object -> String으로

변환해 주는데요.

 

 

 

 

var jsonStr = JSON.parse('{"name":"nata","age":20}');
console.log(typeof(jsonStr));
//result : object

 

 

 

JSON객체에는 stringify라는 함수가 있습니다.

Object를 Json 포멧방식을 가진 상태로

타입을 String으로 변환하는 것입니다.

 

var obj = {name : "nata", age : 20};
var objStr = JSON.stringify(obj);
console.log(objStr);
//result : {"name":"nata","age":20}

 

 

 

 

https://heavenly-appear.tistory.com/375

 

자바스크립트 JSON 객체의 parse 및 stringify 정리.

자바스크립트 JSON의 이해 JSON은 네트워크 데이터 전송방식의 표준 Format으로 사용되고 있습니다. (이외에는 xml, html) Json은 String 문자열이므로 실제 자바스크립트에서 사용하기 위해서는 파싱을

heavenly-appear.tistory.com

 

 

 

 

 

'🌿 Node' 카테고리의 다른 글

express 공부  (0) 2022.02.20
espress 기초 다지기 - 미들웨어편  (0) 2022.02.20
express 파일 구조와 몽고 디비  (0) 2022.02.16
GET, POST, DELETE, PUT  (0) 2022.02.13
노드 이해하기  (0) 2022.02.13