Lsiron

body-parser(파싱과 JSON, 미들웨어, URL-encoded) 본문

백엔드/Node.js

body-parser(파싱과 JSON, 미들웨어, URL-encoded)

Lsiron 2024. 6. 5. 00:18

body-paser가 무엇인지 꼬리에 꼬리를 무는 질문과 답변 형식으로 완벽하게 파헤쳐보자.

body-parser?

body-parser는 Express 애플리케이션에서 클라이언트로부터 전송된 요청의 본문(body)을 파싱(parsing)하는 미들웨어이다. 이를 통해 JSON, URL-encoded 데이터를 쉽게 처리할 수 있다.

 

정의를 이해하기 위해 확실하게 짚고 넘어가 보자. 이해하기 위해 습득이 필요한 단어 

1. 파싱과 JSON 2. 미들웨어 3. URL-encoded

 

1. 파싱이란?

주어진 텍스트 데이터를 분석하여 구조화된 데이터로 변환하는 과정이다.

데이터의 의미를 해석하고, 특정 형식의 데이터에서 유용한 정보를 추출하거나 이를 다른 형식으로 변환하여 쉽게 처리할 수 있도록 한다.

 

그럼 이 Node.js에서 사용하는 파싱이란 무엇일까? 

 

JSON 파싱이 바로 Node.js 에서 두고두고 사용하는 파싱이다.

 

JSON 파싱?

 

JSON파싱은 JSON 형식의 문자열을 자바스크립트 객체로 변환하는 과정이다. 예를 들어, 서버로부터 받은 JSON 데이터를 파싱하여 자바스크립트 객체로 변환하고, 이를 통해 데이터를 쉽게 조작할 수 있다. 

 

JSON 형식의 문자열?

 

JSON (JavaScript Object Notation) 문자열은 키-값 쌍으로 이루어진 데이터 구조를 텍스트로 표현한 것이다. 여기서 각 키는 다음과 같이 문자열로 표현되고, 값은 문자열, 숫자, 배열, 객체, true, false, null 등 다양한 타입을 가질 수 있다. 

 

예시로 나타내 보면 다음과 같다.

{
  "name": "John Doe",
  "age": 30,
  "email": "john.doe@example.com"
}

 

JSON 문자열을 자바스크립트 객체로 변환한 것?

 

예시로 나타내 보면 다음과 같다.

{
  name: "John Doe",
  age: 30,
  email: "john.doe@example.com"
}

 

차이가 보이는가요? name , age, email에 큰 따옴표("  ") 가 벗겨진 것을 볼 수 있다.

 

그렇다면 여기에서 알 수 있는것은? JSON 형식의 문자열을 자바스크립트 객체로 변환한다.(자바스크립트에서 쓸 수있도록 만든다.) = JSON 형식의 문자열에서 키에 감싸져있는 큰 따옴표("  ") 를 벗겨준다~ 그럼 자바스크립트에서 흔히 보는 객체가 된다.

 

이 쉬운 방법을 이렇게나 어렵게도 말하고 있다. 그러면 자동으로 파싱이라는 단어도 뭘 의미하는지 알게 됐을것이다.

 

저 문자열(텍스트 형식의 데이터)을 객체(구조화된 데이터)로 만들어준다 = 파싱한다.

 

그러면 우리는 파싱과 JSON에 대해서 알게 되었다.

 

여기서 하나만 더 알아보자. 그럼 객체(구조화된 데이터)를 문자열(텍스트 형식의 데이터)로 바꾸는 방법도 있지 않을까?

 

있다. 파싱의 반댓말은 바로 '문자열화' 이다. 아래 예시를 봐보자. 

 

<JSON 문자열을 자바스크립트 객체로 변환 (파싱)>

let jsonString = '{"name": "John Doe", "age": 30, "email": "john.doe@example.com"}';
let jsonObject = JSON.parse(jsonString);

console.log(jsonObject.name);  // 출력: "John Doe"
console.log(jsonObject.age);   // 출력: 30
console.log(jsonObject.email); // 출력: "john.doe@example.com"

 

<자바스크립트 객체를 JSON 문자열로 변환 (문자열화)>

let jsonObject = {
  name: "John Doe",
  age: 30,
  email: "john.doe@example.com"
};

let jsonString = JSON.stringify(jsonObject);

console.log(jsonString);  // 출력: '{"name":"John Doe","age":30,"email":"john.doe@example.com"}'

 


위 예시를 보면 이 JSON 파싱이나 문자열화가 자동으로 되는건가? 아니다. 파싱은 JSON.parse() 를 통해, 문자열화는 JSON.stringify()를 통해 하고 있는 것을 볼 수 있다.

 

이렇게 변환을 하기 위해선 JSON.parse() 와 JSON.stringify()  같은 도구가 필요하다. 허나 저렇게 직접 사용할 수 있지만,

 

우리는 백엔드에서 express를 사용하기 때문에 저러한 파싱 작업을 더 쉽게 처리할 수 있도록 도와주는 

body-parser 미들웨어를 사용한다. 여기에서 바로 미들웨어의 개념이 등장하는 것 이다.

 

즉, 일반 변환 작업(JSON.parse, JSON.stringify) VS 더 쉬운 변환 작업(body-parser 미들웨어)

 

2. 미들웨어란?

미들웨어(Middleware)는 Express.js와 같은 웹 프레임워크에서 사용되는 함수로, 요청(Request)과 응답(Response) 사이에서 실행되어 특정 작업을 수행한다. 미들웨어는 요청과 응답 객체에 접근할 수 있으며, 다음 미들웨어 함수로 제어를 전달하거나 응답을 완료할 수 있다.

 

미들웨어의 역할?

 

미들웨어는 다양한 역할을 할 수 있다. 일반적인 사용 사례는 다음과 같다.

1) 요청 데이터 파싱: 요청 본문을 JSON, URL-encoded, 또는 다른 형식으로 파싱한다.

2) 로그: 각 요청에 대한 로그를 기록한다.

3) 인증 및 권한 부여: 사용자가 특정 리소스에 접근할 수 있는지 확인한다.

4) 정적 파일 제공: CSS, JavaScript, 이미지와 같은 정적 파일을 제공한다.

5) 오류 처리: 애플리케이션 내에서 발생하는 오류를 처리한다.

 

우리가 위에서 body-parser 를 다룬 것이 바로 1번 요청 데이터 파싱이다. 나머지는 body-parser가 아닌, morgan ,cors 등을 이용한다.

 

즉, JSON 문자열의 객체로 변환 또는 객체를 JSON 문자열로 변환을 더 쉽게 해주는 도구가 1번 역할을 하는 미들웨어, 바로 body-parser 이다.

 

body-parser 사용방법?

 

1) 'body-parser' 설치

Express 버전 4.16.0 이상에서는 body-parser의 대부분의 기능이 내장되어 있어 별도의 설치가 필요 없다. 하지만 더 복잡한 설정이 필요하다면 body-parser 모듈을 직접 설치하고 사용할 수도 있다. 명령어에 다음과 같이 입력해주자.

$ npm i body-parser

 

 

2) 미들웨어로 'body-parser'를 설정

body-parser를 설정하고 사용하기 위해 Express 애플리케이션에 미들웨어로 추가한다. 

let express = require('express');
let bodyParser = require('body-parser');
let app = express();

// JSON 요청 본문을 파싱하는 미들웨어
app.use(bodyParser.json());

// URL-encoded 요청 본문을 파싱하는 미들웨어
app.use(bodyParser.urlencoded({ extended: true }));

 

위와 같이 작성하면 되는데 나는 저 코드를 외우지도 않았고 이해 하지도 않았다.

 

https://www.npmjs.com/package/body-parser

 

body-parser

Node.js body parsing middleware. Latest version: 1.20.2, last published: a year ago. Start using body-parser in your project by running `npm i body-parser`. There are 25252 other projects in the npm registry using body-parser.

www.npmjs.com

그냥 bode-parser를 사용하기 위해 기본 설정을 이 사이트에서 가져와서 변수명 var만 let으로 바꿔 준 것이다.

 

게임을 할 때 환경설정에 대한 내용을 전부 이해하고 게임을 하는가? 아니다. 그렇다면 하나만 짚고 넘어가보자.

 

app.use(bodyParser.urlencoded({ extended: true })); 여기에서 urlencoded는 무엇일까?

 

3. URL-encoded 란?

URL-encoded 형식은 클라이언트에서 서버로 데이터를 전송하는 방식 중 하나이다. 이 방식은 HTML 폼에서 사용되는 기본 인코딩 방식이며, 데이터를 키-값 쌍으로 인코딩하여 URL에 포함될 수 있도록 한다. 예를 들어, 다음과 같은 URL-encoded 데이터를 생각해볼 수 있다.

name=John+Doe&age=30&email=john.doe@example.com

 

이 데이터는 name, age, email 세 개의 필드와 그에 해당하는 값으로 구성되어 있다. =로 필드와 값이 구분되고, &로 각 필드-값 쌍이 구분된다. 이 때 값은 공백을 +로 인코딩하거나 %20으로 인코딩할 수 있다.

 

=> 인터넷을 돌아다니다 보면 저런 형식의 주소창을 볼 수 있지 않았는가? 즉, URL에 포함된 문자열데이터 라는 뜻이다.

이 말은  bodyParser.urlencoded({ extended: true }) 가 URL에 포함된 문자열 데이터를 자바스크립트 객체로 변환 할 수 있다는 말이다. 

 

그러면 extended : true는 ? 뭘까 ?

 

extended 옵션은 해석된 데이터를 처리하는 방법을 정의한다. 기본적으로는 이 옵션을 false로 설정하여 내장된 querystring 라이브러리를 사용하여 데이터를 해석한다.

(https://lsiron.tistory.com/28 이 게시물에 querystring 내용이 나와있다.)

그러나 extended를 true로 설정하면 데이터를 좀 더 복잡한 형태로 처리할 수 있도록 qs 라이브러리를 사용한다.

 

extended 옵션은 true일 경우 객체 형태로 전달된 데이터내에서 또다른 중첩된 객체를 허용한다는 말이며 false인 경우에는 허용하지 않는다는 의미이다.

 

즉, 객체지향인 자바스크립트에선 중첩된 객체를 사용할 일이 많으니 이를 true로 해 준다는 의미이다.

 

이로써 우리는 첫 글에 보았던 body-parser 미들웨어가 JSON데이터와 URL-encoded 데이터를 어떻게 처리할 수 있는지 알게되었다.

 

외울 필요는 없고 어차피 가져다 쓰는 설정이니 그냥 그래서 그렇구나 로 알면 되겠다.

 

그러면 이제 body-parser 를 사용하여 간단하게 코드를 만들어보자.

let express = require('express');
let bodyParser = require('body-parser');
let app = express();

// JSON 요청 본문을 파싱하는 미들웨어
app.use(bodyParser.json());

// URL-encoded 요청 본문을 파싱하는 미들웨어
app.use(bodyParser.urlencoded({ extended: true }));

app.post('/data', function (req, res) {
  // 요청 본문에서 파싱된 데이터에 접근
  let name = req.body.name;
  let age = req.body.age;
  let email = req.body.email;

  console.log('Name:', name);
  console.log('Age:', age);
  console.log('Email:', email);

  res.send('Data received successfully!');
});

 

위 코드를 분석해보자.

 

body-parser 미들웨어를 사용하기 위해 기본 설정을 해 주었다.

 

그리곤 POST 매서드를 통해 본문에 데이터를 요청하고 응답한다. 즉, /data 는 다음의 JSON 문자열 데이터를 가지고 있던 것이다.

{
  "name": "John Doe",
  "age": 30,
  "email": "john.doe@example.com"
}

 

문자열 상태로는 데이터를 받아 올 수 없으니까 객체 상태로 받아와야한다.

body-parser 설정을 통해 req.body를 써서 객체상태로 변환한 name, age, email을 각각 변수에 담을 수 있게 되었다. (body-parser를 설정하지 않으면 위 예시 처럼 req.body 를 쓰고 console.log로 찍었을때 'undefined'가 출력된다.)

 

즉,  Express와 같은 프레임워크에서 request.body를 사용할 수 있도록 하기 위해서는 body-parser와 같은 미들웨어가 필요하다.

 

req.? body.name? 무슨 소리지 이게? 

 

직역하면 이렇다. 요청한다.본문.name => 그러니까 본문에 있는 name을 요청한다는 말이다.

 

의역하면, 나 body-parser 설정했으니까 /data에 문자열 데이터로 되어있는 name을 객체화 시켜서 let name 에 넣어줘.

 

그러면 console.log로 name을 찍었을때, name: John Doe 가 출력된다.

 

마지막 res.send('Data received successfully!'); 이것도 직역하면, 응답.보낸다. 'Data received successfully!'

'Data received successfully!' 내용을 응답으로 보낸다는 것이다. 

 

그러면 화면에는 Data received successfully! 가 표시될 것이다.