TIL

Node.js 복습 (2) ( app.js, mongooseSchema )

황민도 2024. 7. 5. 16:17

내일배움캠프 스파르타 코딩클럽

 

<schemas. product.schema.js>

import mongoose from 'mongoose';

// 제품 스키마 정의
const productSchema = new mongoose.Schema({
    name: {
        type: String,
        required: true, // 필수 항목
        unique: true, // 유일한 값이어야 함
    },
    // 추가 필드를 여기에 정의할 수 있습니다.
    // 예를 들어:
    price: {
        type: Number,
        required: true, // 필수 항목
    },
    inStock: {
        type: Boolean,
        default: true, // 기본 값 설정
    },
    createdAt: {
        type: Date,
        default: Date.now, // 생성 시간 자동 설정
    },
});

// 모델 생성
const Product = mongoose.model('Product', productSchema);

export default Product;

 

required: 입력받을때 필수항목 지정을 나타냄

unique: 유일한 값

 

mongoose 가 어떤 타입을 제공하는지 궁금하다면? (공식문서 참고)

https://mongoosejs.com/docs/schematypes.html#schematype-options

 

Mongoose v8.4.5: SchemaTypes

SchemaTypes SchemaTypes handle definition of path defaults, validation, getters, setters, field selection defaults for queries, and other general characteristics for Mongoose document properties. You can think of a Mongoose schema as the configuration obje

mongoosejs.com


import mongoose from 'mongoose';
import { PRODUCT_STATUS } from '../constants/product.constant.js';

const productSchema = new mongoose.Schema(
  {
    name: {
      type: String,
      required: true,
      unique: true,
    },
    description: {
      type: String,
      required: true,
    },
    manager: {
      type: String,
      required: true,
    },
    password: {
      type: String,
      required: true,
      select: false,
    },
    status: {
      type: String,
      required: true,
      enum: Object.values(PRODUCT_STATUS),
      default: PRODUCT_STATUS.FOR_SALE,
    },
  },
  { timestamps: true, toJSON: { virtuals: true } },
);

export const Product = mongoose.model('Product', productSchema)

 

timestamps: https://mongoosejs.com/docs/guide.html#timestamps

 

Mongoose v8.4.5: Schemas

Schemas If you haven't yet done so, please take a minute to read the quickstart to get an idea of how Mongoose works. If you are migrating from 7.x to 8.x please take a moment to read the migration guide. Everything in Mongoose starts with a Schema. Each s

mongoosejs.com


toJSON: { virtuals: true } 설정

 

예시:

// 가상 속성 추가 (예: fullDescription)
productSchema.virtual('fullDescription').get(function () {
    return `${this.name} - ${this.description}`;
});

 

// 예제 데이터 생성
const product = new Product({
    name: 'Example Product',
    description: 'This is an example product.',
    manager: 'John Doe',
    password: 'secretPassword',
    status: PRODUCT_STATUS.FOR_SALE,
});
 
// JSON 변환
const productJSON = product.toJSON();
console.log(productJSON);

 

{
    "_id": "60d21b4667d0d8992e610c85",
    "name": "Example Product",
    "description": "This is an example product.",
    "manager": "John Doe",
    "status": "for_sale",
    "createdAt": "2023-07-07T00:00:00.000Z",
    "updatedAt": "2023-07-07T00:00:00.000Z",
    "fullDescription": "Example Product - This is an example product."
}

 


< src. app.js >

import express from 'express';
import { SERVER_PORT } from './constants/env.constant.js';

const app = express();

app.use(express.json()) //body 에 있는 json 을 반영
app.use(express.urlencoded({ extended: true })) // form 으로 넘어오는 데이터를 body로 돌려주는 역할

app.listen(SERVER_PORT, () => {
  console.log(`Server is listening on ${SERVER_PORT}`);
});

 

1. 나 ( 질문 ) :

app.use(express.json()) 이 body에 있는 json을 반영해주는 역할 이라고 하는데 use가 무슨 역할이며

express.json() 이 use 파라미터 안에 들어가면 어떠한 값과 같은지도 궁금하고

body에 있는 json을 어떻게 반영해주는지도 궁금해

 

2. ChatGPT (출처: ChatGPT ) :

 

app.use 의 역할

app.use 는 Express.js 애플리케이션에서 미들웨어를 추가하는 데 사용됩니다.

미들웨어는 요청(request)과 응답(response) 객체에 접근할 수 있는 함수이며, 요청 처리 과정에서 여러 작업을

수행할 수 있습니다.

 

express.json() 의 역할

express.json() 은 Express.js 내장 미들웨어 함수로, 들어오는 요청의 본문(body) 을 JSON으로 파싱합니다.

이를 통해 클라이언트가 보낸 JSON 데이터를 서버에서 JavaScript 객체로 쉽게 접근하고 조작할 수 있게 해줍니다.

 

app.use(express.json()) 의 작동 방식

app.use(express.json()) 를 호출하면 다음과 같은 작업이 수행됩니다.

 

1. 요청 본문 파싱: 요청의 Content-Type이 application/json 인 경우, 본문을 자동으로 파싱하여

req.body에 저장합니다.

 

2. 오류 처리: JSON  파싱 중 오류가 발생하면, 클라이언트에게 400 Bad Request 응답을 보냅니다.

 

express.json() 의 반환값

express.json() 은 미들웨어 함수입니다. 이 함수는 요청(req), 응답(res), 그리고 다음 미들웨어 함수(next)에 대한

세 개의 인수를 받습니다.

 

예제 :

아래는 app.use(express.json()) 를 사용하는 간단한 예제입니다.

import express from 'express';

const app = express();

// JSON 본문 파싱 미들웨어 추가
app.use(express.json());

// 예제 라우트
app.post('/example', (req, res) => {
  const jsonData = req.body;
  console.log(jsonData); // { key: 'value' }
  res.send('JSON data received');
});

app.listen(3000, () => {
  console.log('Server is running on port 3000');
});

 

작동 방식 :

 

1. 클라이언트 요청: 클라이언트가 아래와 같은 JSON 데이터를 POST 요청으로 /example 엔드포인트에 보냅니다.

{
  "key": "value"
}

 

2. express.json() 미들웨어:

- 요청 본문의 Content-Type 이 application/json 인지 확인합니다.

- JSON 데이터를 파싱하여 JavaScript 객체로 변환합니다.

- 변환된 객체를 req.body 에 저장합니다.

 

3. 라우트 핸들러:

 - req.body 를 통해 파싱된 JSON 데이터에 접근합니다.

 - 데이터를 사용하여 필요한 작업을 수행합니다.

 

이 과정을 통해 JSON 형식의 요청 본문이 Express.js 애플리케이션에서 쉽게 처리 될 수 있습니다.

app.use(express.json()) 는 이처럼 JSON 본문 파싱을 자동화하여 개발자가 요청 데이터를 더 편리하게

다룰 수 있도록 해줍니다.


1. 나 ( 질문 ) : 

Content-Type 이 그냥 type of 같은 type의 종류를 말하는 것 이며 application/json 은

그 type 중 하나인 json 을 application/json 이라고 적은거야?

 

2. ChatGPT (출처: ChatGPT ) :

 

Content-Type: 

Content-Type 헤더는 HTTP 요청과 응답에서 데이터의 유형을 지정 하는데 사용됩니다.

이는 클라이언트와 서버가 데이터 형식을 이해하고 처리할 수 있도록 합니다.

 

Content-Type 헤더

Content-Type 헤더 요청(request) 또는 응답(response) 본문(body)의 데이터 형식을 나타냅니다.

형식은 타입/하위타입  ( type/subtype ) 구조를 따릅니다.

 

application/json은 MIME 타입 중 JSON (javaScript) Object Notation) 형싱의 데이터를 나타냅니다.

이 타입은 데이터를 JSON 형식으로 인코딩하여 전송한다는 것을 의미합니다.

 

예시:

JSON 데이터 전송

클라이언트가 서버로 JSON 데이터를 보낼 때, Content-Type 헤더를 application/json 으로 설정합니다.

예를 들어, 클라이언트가 아래와 같은 HTTP POST 요청을 보낸다고 가정해 봅시다.

POST /example HTTP/1.1
Host: example.com
Content-Type: application/json
Content-Length: 18

{
  "key": "value"
}

 

서버 설정

서버에서는 express.json() 미들웨어를 사용하여  JSON 형식의 요청 본문을 자동으로 파싱합니다.

import express from 'express';

const app = express();

// JSON 본문 파싱 미들웨어 추가
app.use(express.json());

// 예제 라우트
app.post('/example', (req, res) => {
  const jsonData = req.body;
  console.log(jsonData); // { key: 'value' }
  res.send('JSON data received');
});

app.listen(3000, () => {
  console.log('Server is running on port 3000');
});

 

이 예제에서 클라이언트가 JSON 데이터를 서버로 전송하면, express.json() 미들웨어가

요청 본문의 Content-Type 을 확인하고, application/json 인 경우 데이터를 파싱하여 req.body 에 저장합니다.

그 결과, 서버는 JSON 데이터를 JavaScript 객체로 접근할 수 있게 됩니다.

 

요약 

 - Content-Type 은 HTTP 요청/응답에서 데이터 형식을 지정하는 헤더입니다.

 - application/json 은 JSON 형식의 데이터를 나타내는 Content-Type 입니다.

 - express.json() 미들웨어는 Content-Type 이 application/json 인 요청의 본문을 자동으로 파싱하여 JavaScript

 객체로 변환합니다.

 

이런 방식으로 클라이언트와 서버 간의 데이터 전송이 효율적이고 일관되게 이루어질 수 있습니다.


< src. app.js >

import express from 'express';
import { SERVER_PORT } from './constants/env.constant.js';

const app = express();

app.use(express.json()); //body 에 있는 json 을 반영
app.use(express.urlencoded({ extended: true })); // form 으로 넘어오는 데이터를 body로 돌려주는 역할

app.listen(SERVER_PORT, () => {
  console.log(`Server is listening on ${SERVER_PORT}`);
});

 

1. 나 ( 질문 ) :

app.use(express.urlencoded({ extended: true })); // form 으로 넘어오는 데이터를 body로 돌려주는 역할 이라고 배웠는데 form이 어디를 뜻하며 urlencoded메서드 파라미터에 객체가 들어가는 이유가 무엇이고 extended는 무엇을 뜻하며 extended 외에 다른 무엇이 또 들어갈 수 있는지도 알려줘

 

2. ChatGPT (출처: ChatGPT ) :

express.urlencoded() 는 Express.js 미들웨어로, HTML 폼 데이터를 처리하기 위한 역할을 합니다.

주로 폼 데이터가 서버로 전송될 때 이를 파싱하여 req.body 객체로 만들어줍니다.

 

Form의 의미

form 은 HTML 문서에서 사용되는 <form> 태그를 의미합니다.

사용자가 웹페이지에서 입력한 데이터를 서버로 전송하깆 위해 사용됩니다.

일반적으로 다음과 같은 형태로 사용됩니다.

<form action="/submit" method="POST">
  <input type="text" name="username">
  <input type="password" name="password">
  <button type="submit">Submit</button>
</form>

이 폼이 제출되면 입력된 데이터는 URL-encoded 형식으로 서버로 전송됩니다.

 

express.urlencoded()의 파라미터

express.urlencoded() 는 다음과 같은 객체를 파라미터로 받습니다.

app.use(express.urlencoded({ extended: true }));

여기서 extended 는 파싱 방법을 결정합니다.

 

extended 옵션

 - extended: true : qs 라이브러리를 사용하여 URL-encoded 데이터를 파싱합니다.

이방식은 중첩된 객체를 지원합니다.

 - extended: false : 기본 내장된 querystring 모듈을 사용하여 URL-encoded 데이터를 파싱합니다.

이방식은 중첩된 객체를 지원하지 않습니다.

 

예를 들어

// extended: true
app.use(express.urlencoded({ extended: true }));

이렇게 설정하면 다음과 같은 중첩된 객체도 파싱이 가능합니다.

name=John&address[city]=NewYork&address[zip]=10001

이 경우 req.body는 다음과 같습니다.

{
  name: 'John',
  address: {
    city: 'NewYork',
    zip: '10001'
  }
}

반면에 extended: false 로 설정하면 중첩된 객체를 지원하지 않습니다.

 

전체 설정 예시

다음은 Express.js 애플리케이션에서 express.urlencoded() 를 사용하는 전체 예시입니다.

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

app.use(express.urlencoded({ extended: true }));

app.post('/submit', (req, res) => {
  console.log(req.body);
  res.send('Form data received');
});

app.listen(3000, () => {
  console.log('Server is running on port 3000');
});

이 예시에서, 폼 데이터를 서버로 전송하면 express.urlencoded() 미들웨어가 이를 파싱하여

req.body 객체로 만들어줍니다. 이후 req.body 를 사용하여 폼 데이터를 처리할 수 있습니다.

 

다른 옵션들

express.urlencoded() 는 기본적으로 extended 옵션 외에 다른 옵션을 받지 않습니다.

하지만 express.json() 과 같이 다른 미들웨어는 다양한 옵션을 받을 수 있습니다. 예를 들어

app.use(express.json({ limit: '1mb' }));

이 코드에서는 JSON 바디의 최대 크기를 1MB로 제한하는 limit 옵션을 설정합니다.

 

따라서 express.urlencoded() 에서 주로 사용하는 옵션은 extended 이며, 이 옵션이 true인지 false인지에 따라 

파싱되는 데이터의 형식이 달라집니다.