w e b & s e r v e r

์„œ๋ฒ„ ๊ธฐ์ดˆ Express / ์š”์ฒญ๊ณผ ์‘๋‹ต ๋ฐ์ดํ„ฐ JSON ์ง๋ ฌํ™”, ์—ญ์ง๋ ฌํ™”

hee.hee 2022. 6. 19. 20:47
 


๐Ÿ’พ ์„œ๋ฒ„ ๊ธฐ์ดˆ Express / ์š”์ฒญ๊ณผ ์‘๋‹ต ๋ฐ์ดํ„ฐ JSON ์ง๋ ฌํ™”, ์—ญ์ง๋ ฌํ™”

๐Ÿ“‚ ๋ฐ”๋”” ์–ป๋Š” ๋ฐฉ๋ฒ•์˜ ์ข…๋ฅ˜ (express.json( ))
๐Ÿ“‚ JSON๊ณผ ์ง๋ ฌํ™”, ์—ญ์ง๋ ฌํ™”
๐Ÿ“‚ Fetch์™€ JSON
๐Ÿ“‚ mini node server ๊ณผ์ œ
๐Ÿ“‚ res.json( )
๐Ÿ“‚ mini node server์—์„œ ๋ฐ์ดํ„ฐ๊ฐ€ ์˜ค๊ณ ๊ฐ€๋Š” ๊ณผ์ • (์š”์•ฝ)






๐Ÿ“‚ ๋ฐ”๋”” ์–ป๋Š” ๋ฐฉ๋ฒ•์˜ ์ข…๋ฅ˜ (express.json( ))


๐Ÿ“Ž Node.js / Buffer

Node.js ๋งŒ ์‚ฌ์šฉํ•ด์„œ post ์š”์ฒญ ์‹œ, HTTP body๋ฅผ ๋ฐ›์•„์˜ค๋Š” ๊ณผ์ •์ด ์ข€ ๋ณต์žกํ•˜๋‹ค.
๋„คํŠธ์›Œํฌ ์ƒ์˜ chunk๋ฅผ ํ•ฉ์น˜๊ณ , buffer๋ฅผ ๋ฌธ์ž์—ด๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ์ž‘์—…์ด ํ•„์š”ํ•˜๋‹ค.

let body = [];
request.on('data', (chunk) => {
  body.push(chunk);
}).on('end', () => {
  body = Buffer.concat(body).toString();
  // body ๋ณ€์ˆ˜์—๋Š” ๋ฌธ์ž์—ด ํ˜•ํƒœ๋กœ payload๊ฐ€ ๋‹ด๊ฒจ์ ธ ์žˆ์Šต๋‹ˆ๋‹ค.
});



๐Ÿ“Ž Express / bodyparser.json()

์œ„์˜ ์ž‘์—…์€ express ๋ฏธ๋“ค์›จ์–ด express.json์œผ๋กœ ๊ฐ„๋‹จํ•˜๊ฒŒ ๋ฐ”๊ฟ€ ์ˆ˜ ์žˆ๋‹ค.
ํ•˜์ง€๋งŒ, express.json() ์ด์ „์— ์‚ฌ์šฉํ–ˆ๋˜ body-parser ๋จผ์ € ๋ณด์ž.
npm์œผ๋กœ bodyparser๋ฅผ ์„ค์น˜ํ•ด์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

const bodyParser = require('body-parser');
const jsonParser = bodyParser.json();

// ์ƒ๋žต
app.post('/users', jsonParser, function (req, res) {

})

์š”๋ ‡๊ฒŒ. (๋‚ด๊ฐ€) ์ฃผ์˜ํ•  ์ ์€, ๊ทธ๋ƒฅ bodyparser๊ฐ€ ์•„๋‹ˆ๋ผ, .json() ๋ฉ”์„œ๋“œ๋ฅผ ๋ถ™์—ฌ์„œ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋‹ค.
bodyParser.json()์€ application/json ๋ฐฉ์‹์˜ Content-Type ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ›์•„์˜จ๋‹ค.
request๋ฅผ ์œ„ํ•ด body๋ฅผ json ํƒ€์ž…์˜ ๋ฐ์ดํ„ฐ๋กœ ๋ฐ”๊ฟ”์ฃผ๋Š” ๊ฒƒ์ด๋‹ค.




๐Ÿ“Ž Express / express.json()

bodyparser.json()์€ npm์œผ๋กœ ์„ค์น˜ํ•ด์„œ ์“ธ ์ˆ˜ ์žˆ์—ˆ์ง€๋งŒ,
Express v4.16.0 ๋ถ€ํ„ฐ๋Š” body-parser๋ฅผ ๋”ฐ๋กœ ์„ค์น˜ ํ•˜์ง€ ์•Š๊ณ , Express ๋‚ด์žฅ ๋ฏธ๋“ค์›จ์–ด์ธ express.json()์„ ์‚ฌ์šฉํ•œ๋‹ค.

const jsonParser = express.json();

// ์ƒ๋žต
app.post('/api/users', jsonParser, function (req, res) {

})

jsonparser์— express.json() ๋ฏธ๋“ค์›จ์–ด๋ฅผ ํ• ๋‹นํ•ด์„œ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋‹ค.์šฐ๋ฆฌ๋Š” ์ด์ œ, node.js์—์„œ request .on์œผ๋กœ ๋ฐ์ดํ„ฐ๊ฐ€ ๋“ค์–ด์˜ค๋ฉด chunk๋ฅผ ๊ฐ€์ง€๊ณ  Buffer์— ๋ชจ์•„์„œ ๊ทธ๊ฑธ ์ŠคํŠธ๋ง์œผ๋กœ ๋ฐ”๊ฟ” ๋ฐ”๋””๋กœ ๋ณด๋‚ด๊ณ .. ๋“ฑ๋“ฑ ํ•  ํ•„์š” ์—†์ด express.json() ๋ฏธ๋“ค์›จ์–ด๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๊ฐ„๋‹จํ•˜๊ฒŒ ์š”์ฒญ์˜ ๋ฐ”๋””๋ฅผ json ๋ฐ์ดํ„ฐ ํƒ€์ž…์œผ๋กœ ๋ฐ›์•„์˜ฌ ์ˆ˜ ์žˆ๋‹ค.

์ถ”๊ฐ€๋กœ, express.json()์˜ ์˜ต์…˜ ์ค‘, strict๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. ๋ณดํ†ต json ํ˜•ํƒœ๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ๋ฐ์ดํ„ฐ๋Š” ๊ฐ์ฒด ํ˜น์€ ๋ฐฐ์—ด์ด๋‹ค. json์œผ๋กœ ๋ฐ›๋Š” ๋ฐ”๋””์˜ ๋ฐ์ดํ„ฐ๊ฐ€ ๊ฐ์ฒด, ๋ฐ”๋””์ธ์ง€ ํ™•์ธํ•˜๋Š” ์˜ต์…˜์ด๋‹ค. default๊ฐ€ true์ด๊ณ , ๊ฐ์ฒด ํ˜น์€ ๋ฐฐ์—ด๋งŒ ๋ฐ”๋””๋กœ ๋ฐ›์•„ json์œผ๋กœ ๋ณ€ํ™˜ํ•ด์ค€๋‹ค.
false๋กœ ๋ฐ”๊พธ๋ฉด ๋ชจ๋“  ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ค ๋ฐ›์„ ์ˆ˜ ์žˆ๋‹ค. ์šฐ๋ฆฌ ๊ณผ์ œ์—์„œ ๋ฐ›์•„์™€์•ผ ํ•˜๋Š” ๋ฐ”๋””๋Š” ๊ทธ๋ƒฅ ์ŠคํŠธ๋ง์ด๋ผ์„œ strict๋ฅผ false๋กœ ์ค˜์•ผํ•œ๋‹ค.

const jsonParser = express.json({ strict: false });






์—ฌ๊ธฐ๊นŒ์ง„ ๋‚ฉ๋“ํ–ˆ๋‹ค. ์˜ค์ผ€์ด.
๊ทธ๋Ÿฐ๋ฐ ๊ณผ์ œ๋ฅผ ํ•˜๋ฉด์„œ ํ•œ ๊ฐ€์ง€ ์˜๋ฌธ์ด ๊ณ„์† ๋‚˜๋ฅผ ๊ดด๋กญํ˜”๋‹ค.

์™œ ์š”์ฒญ์„ ๋ณด๋‚ผ ๋•Œ๋Š” express.json()์„ ํ†ตํ•ด jsonํ˜•์‹์œผ๋กœ body๋ฅผ ์ง๋ ฌํ™” ํ•ด์„œ ๋ณด๋‚ด์ฃผ๊ณ ,
๋ฐ›์•„์˜ฌ ๋•Œ๋Š” ์™œ ๋‹ค์‹œ ์—ญ์ง๋ ฌํ™”๋ฅผ ํ•˜์ง€ ์•Š๋Š” ๊ฑธ๊นŒ

๋‚˜๋Š” ์ด ์ƒ๊ฐ์— ์‹œ๋‹ฌ๋ฆฌ๋‹ค๊ฐ€ ๊ถ๊ธˆ์ฆ์ด ํ’€๋ฆฌ์ง€ ์•Š์•„ ๋„ˆ๋ฌด ํž˜๋“ค์—ˆ๋‹ค.
๊ทธ๋Ÿฌ๋˜ ์ค‘ ๋™๊ธฐ๋ถ„์ด ๊ฐ์‚ฌํ•˜๊ฒŒ๋„ ์‹ค๋งˆ๋ฆฌ๋ฅผ ํ’€์–ด์ฃผ์…จ๋‹ค. ๊ฐ๋™๋ฐ›๊ณ  ๋ˆˆ๋ฌผ์„ ํ˜๋ ธ๋‹ค(์ •๋ง).

๋จผ์ € json ์ง๋ ฌํ™”์™€ ์—ญ์ง๋ ฌํ™”๋ฅผ ์ž ๊น ์ด์•ผ๊ธฐ ํ•˜๊ณ  ์ฝ”๋“œ๋ฅผ ๋ณด์ž.




๐Ÿ“‚ JSON๊ณผ ์ง๋ ฌํ™”, ์—ญ์ง๋ ฌํ™”


๐Ÿ“Ž JSON

JSON์€ ํด๋ผ์ด์–ธํŠธ์™€ ์„œ๋ฒ„ ๊ฐ„์˜ HTTP ํ†ต์‹ ์„ ์œ„ํ•œ ๋ฐ์ดํ„ฐ ํฌ๋งท์ด๋‹ค. ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์— ์ข…์†๋˜์ง€ ์•Š๋Š” ์–ธ์–ด ๋…๋ฆฝํ˜• ํฌ๋งท์œผ๋กœ, ๋Œ€๋ถ€๋ถ„์˜ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. JSON์˜ ํ‚ค๋Š” ๋ฐ˜๋“œ์‹œ ํฐ๋”ฐ์˜ดํ‘œ๋กœ ๋ฌถ์–ด์•ผ ํ•œ๋‹ค. ๊ฐ’์€ ๊ฐ์ฒด ๋ฆฌํ„ฐ๋Ÿด๊ณผ ๊ฐ™์€ ํ‘œ๊ธฐ๋ฒ•์„ ๊ทธ๋Œ€๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. ํ•˜์ง€๋งŒ ๋ฌธ์ž์—ด์€ ๋ฐ˜๋“œ์‹œ ํฐ๋”ฐ์˜ดํ‘œ๋กœ ๋ฌถ์–ด์•ผ ํ•œ๋‹ค. ๋ฐ‘์˜ ์˜ˆ์‹œ์ฒ˜๋Ÿผ.

{
   "name": "hee",
    "age": 99,
    "alive": true,
    "hobby": ["์…œ๋ก์ด์™€ ์‚ฐ์ฑ…"]
}

 

๐Ÿ“Ž serializing, JSON.stringify( )

ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์„œ๋ฒ„๋กœ ๊ฐ์ฒด๋ฅผ ์ „์†กํ•˜๋ ค๋ฉด ๊ฐ์ฒด๋ฅผ ๋ฌธ์ž์—ดํ™” ํ•ด์•ผํ•œ๋‹ค. ์ด๋ฅผ ์ง๋ ฌํ™”(serializing)๋ผ๊ณ  ํ•œ๋‹ค. JSON ์ง๋ ฌํ™” ๋ง๊ณ ๋„, ๋ฐ”์ด๋„ˆ๋ฆฌ, XML ์ง๋ ฌํ™”๊ฐ€ ์žˆ๋‹ค. JSON์€ JS๋ง๊ณ  ๋‹ค๋ฅธ ์–ธ์–ด์—์„œ๋„ ์ด์šฉํ•  ์ˆ˜ ์žˆ์–ด์„œ ๋‹ค์–‘ํ•œ ์†Œํ”„ํŠธ์›จ์–ด ๊ฐ„ ๋ฐ์ดํ„ฐ๋ฅผ ์ฃผ๊ณ  ๋ฐ›์„ ๋•Œ ์œ ์šฉํ•˜๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. JSON.stringify()์€ ๊ฐ์ฒด ๋ฟ ์•„๋‹ˆ๋ผ ๋ฐฐ์—ด๊ณ  JSON ํฌ๋งท์˜ ๋ฌธ์ž์—ด๋กœ ๋ณ€ํ™˜์‹œํ‚จ๋‹ค.

๐Ÿ“Ž deserializing, JSON.parse( )

์„œ๋ฒ„๋กœ๋ถ€ํ„ฐ ํด๋ผ์ด์–ธํŠธ์—๊ฒŒ ์ „์†ก๋œ JSON ๋ฐ์ดํ„ฐ๋Š” ๋ฌธ์ž์—ด์ด๋‹ค. ์ด ๋ฌธ์ž์—ด์„ ๊ฐ์ฒด๋กœ์„œ ์‚ฌ์šฉํ•˜๋ ค๋ฉด JSON ํฌ๋งจ์˜ ๋ฌธ์ž์—ด์„ ๊ฐ์ฒดํ™”ํ•ด์•ผ ํ•œ๋‹ค. ์ด๋ฅผ ์—ญ์ง๋ ฌํ™”๋ผ๊ณ  ํ•œ๋‹ค. ์ด๋•Œ ์‚ฌ์šฉํ•˜๋Š” ๋ฉ”์„œ๋“œ๊ฐ€ JSON.parse()์ด๋‹ค.

 

  ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๊ฐ์ฒด JSON
ํ‚ค ํ‚ค๋Š” ๋”ฐ์˜ดํ‘œ ์—†์ด ์“ธ ์ˆ˜ ์žˆ์Œ
{ key : "property" }
๋ฐ˜๋“œ์‹œ ์Œ๋”ฐ์˜ดํ‘œ๋ฅผ ๋ถ™์—ฌ์•ผ ํ•จ
'{"key":"property"}'
๋ฌธ์ž์—ด ๊ฐ’ ์ž‘์€๋”ฐ์˜ดํ‘œ๋„ ์‚ฌ์šฉ ๊ฐ€๋Šฅ
{ "key" : 'property' }
๋ฐ˜๋“œ์‹œ ํฐ๋”ฐ์˜ดํ‘œ๋กœ ๊ฐ์‹ธ์•ผ ํ•จ
'{"key":"property"}'
ํ‚ค์™€ ๊ฐ’ ์‚ฌ์ด ๊ณต๋ฐฑ ์‚ฌ์šฉ ๋ถˆ๊ฐ€๋Šฅ
{"key":"property"}
์‚ฌ์šฉ ๊ฐ€๋Šฅ
'{ "key" : 'property' }'
ํ‚ค-๊ฐ’ ์Œ ์‚ฌ์ด ๊ณต๋ฐฑ ์‚ฌ์šฉ ๊ฐ€๋Šฅ
{ "key":'property', num:1 }
์‚ฌ์šฉ ๋ถˆ๊ฐ€๋Šฅ
'{"key":"property","num":1}'
 



๐Ÿ“‚ Fetch์™€ JSON


๊ทธ๋ฆฌ๊ณ  ๋˜ ์ฃผ์˜ํ•  ์ , Fetch!
HTTP ์š”์ฒญ์„ ์ „์†กํ•˜๋Š” ํด๋ผ์ด์–ธํŠธ ์‚ฌ์ด๋“œ API์ธ fetch์—์„œ๋„ ๋‹น์—ฐํžˆ JSON์„ ์‚ฌ์šฉํ•œ๋‹ค. fetch ํ•จ์ˆ˜์—๋Š” HTTP ์š”์ฒญ์„ ์ „์†กํ•  URL๊ณผ HTTP ์š”์ฒญ ๋ฉ”์„œ๋“œ, HTTP ์š”์ฒญ ํ—ค๋”, ํŽ˜์ด๋กœ๋“œ ๋“ฑ์„ ์„ค์ •ํ•œ ๊ฐ์ฒด๋ฅผ ์ „๋‹ฌํ•œ๋‹ค.
๊ทธ๋Ÿฐ๋ฐ fetch ํ•จ์ˆ˜๋กœ ์š”์ฒญํ•œ ๊ฒฐ๊ณผ๋Š” (๋‹น์—ฐํ•˜๊ฒŒ๋„) ๋‚ด๊ฐ€ ์›ํ•˜๋Š” ๊ฐ’๋งŒ ์™ ๋‚˜์˜ค๋Š” ๊ฒŒ ์•„๋‹ˆ๋‹ค.
fetch ํ•จ์ˆ˜๋Š” HTTP ์‘๋‹ต์„ ๋‚˜ํƒ€๋‚ด๋Š” Response ๊ฐ์ฒด๋ฅผ ๋ž˜ํ•‘ํ•œ Promise ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

// fetch ์š”์ฒญ์„ ๋ณด๋‚ด๊ณ  ๋ฐ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์ฝ”๋“œ

post(path, body) {
    fetch(`http://localhost:4999/${path}`, {
      method: "POST",
      body: JSON.stringify(body),
      headers: {
        "Content-Type": "application/json",
      },
    })
      .then((res) => {
        console.log(res);
        console.log(res.json());
        res.json();
      })
      .then((json) => {
        this.render(json);
      });
  }

์œ„์˜ ์ฝ”๋“œ, ์š”์ฒญ input์— '์†Œ๋ฌธ์ž z' ์ž…๋ ฅ ์‹œ ์ฝ˜์†”์ฐฝ

response ๊ฐ์ฒด์— body: (...) ์ด ๋ณด์ธ๋‹ค. ๋ฐ”๋”” ์•ˆ์—๋Š” readablestream ์ด ์žˆ๋‹ค.
๊ทธ๋ฆฌ๊ณ  PromiseResult์—๋Š” ๋‚ด๊ฐ€ ๋ณด๋‚ธ ์†Œ๋ฌธ์ž 'z'์— ๋Œ€ํ•œ ์‘๋‹ต์ธ ๋Œ€๋ฌธ์ž 'Z'๊ฐ€ ๋“ค์–ด๊ฐ€ ์žˆ๊ณ , ํ’€ํ•„๋“œ ์ƒํƒœ์ด๋‹ค.

(์‚ฌ์‹ค ์ด ๋ถ€๋ถ„์ด ์•„์ง ์ดํ•ด๊ฐ€ ์•ˆ๊ฐ„๋‹ค. ํ”„๋กœ๋ฏธ์Šค ์•ˆ์˜ ๋ฆฌ์Šคํฐ์Šค๋„ ์•„๋‹ˆ๊ณ , ๋ฆฌ์Šคํฐ์Šค๊ฐ€ ๋จผ์ € ๋‚˜์˜ค๋Š” ์ด์œ ๊ฐ€ ๋ญ˜๊นŒ? ์•„๋งˆ readablestream์— ๋Œ€ํ•ด ๊ณต๋ถ€ํ•˜๋ฉด ๊ถ๊ธˆ์ฆ์ด ํ’€๋ฆด ๋“ฏํ•˜๋‹ค)
๊ทธ๋Ÿผ ์ด ์ƒํƒœ์—์„œ ๋ณธ๊ฒฉ์ ์œผ๋กœ ๊ณผ์ œ ์ฝ”๋“œ๋ฅผ ๋ณด์ž.






๐Ÿ“‚ mini node server ๊ณผ์ œ


//basic-server.js
//๋ฆฌํŒฉํ† ๋งํ•˜๋ฉฐ ์ถ”๊ฐ€ํ•œ ๋ถ€๋ถ„
const express = require("express");
const app = express();
const jsonParser = express.json({ strict: false });
const cors = require("cors");
//
const http = require("http");
const PORT = 4999;
const ip = "localhost";

app.use(cors());

app.get("/", (req, res) => {
  // get์„ ํ•ด์ฃผ์ง€ ์•Š์œผ๋ฉด ์„œ๋ฒ„์— 'cannot GET /'์ด ๋œฌ๋‹ค.
  res.send("Hello World!");
});

app.post("/lower", jsonParser, function (req, res) {
  res.json(req.body.toLowerCase());
});

app.post("/upper", jsonParser, function (req, res) {
  res.json(req.body.toUpperCase());
});

app.listen(PORT, () => {
  console.log(`Example app listening on port ${PORT}`);
});

์ต์Šคํ”„๋ ˆ์Šค ๋ฏธ๋“ค์›จ์–ด๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋‹ค.
ํŠน์ • ์—”๋“œํฌ์ธํŠธ๋กœ ๋“ค์–ด์˜จ ์š”์ฒญ์˜ ๋ฐ”๋””๋ฅผ ๋ฐ›๊ณ , ๊ทธ ๋ฐ”๋””์˜ ์ŠคํŠธ๋ง์„ toLowerCase/toUpperCase ํ•ด์„œ ์‘๋‹ต์œผ๋กœ ๋Œ๋ ค์ค€๋‹ค.
์—ฌ๊ธฐ์„œ ์‘๋‹ต์€ ๊ทธ๋ƒฅ send๋กœ ์ฃผ๋ฉด ์•ˆ๋œ๋‹ค. .json()์„ ํ†ตํ•ด, ๋ธŒ๋ผ์šฐ์ €๋กœ json๋ฐ์ดํ„ฐ๋กœ ๋ฐ”๊ฟ” ๋ณด๋‚ด์ค€๋‹ค.

(์š”์ฒญ) ๋ฐ”๋””๋ฅผ ๋ฐ›์„ ๋•Œ express.json() ์œผ๋กœ string -> json
(์‘๋‹ต) ๋ฐ”๋””๋ฅผ ๋ณด๋‚ผ ๋•Œ .json()์œผ๋กœ string -> json

๊ทธ๋Ÿผ, ๋ธŒ๋ผ์šฐ์ €๋Š” json ํ˜•์‹์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์–ด๋–ป๊ฒŒ ์‚ฌ์šฉํ• ๊นŒ?



์ด ์ฝ”๋“œ์˜ fetch .then์œผ๋กœ ์‘๋‹ต ๊ฐ์ฒด๊ฐ€ ๋“ค์–ด์˜จ๋‹ค.

// App.js
class App {
  init() {
    document
      .querySelector("#to-upper-case")
      .addEventListener("click", this.toUpperCase.bind(this));
    document
      .querySelector("#to-lower-case")
      .addEventListener("click", this.toLowerCase.bind(this));
  }
  post(path, body) {
    fetch(`http://localhost:4999/${path}`, {
      method: "POST",
      body: JSON.stringify(body),
      headers: {
        "Content-Type": "application/json",
      },
    })
      .then(
        (res) => res.json()
      )
      .then((json) => {
        this.render(json);
      });
  }
  toLowerCase() {
    const text = document.querySelector(".input-text").value;
    this.post("lower", text);
  }
  toUpperCase() {
    const text = document.querySelector(".input-text").value;
    this.post("upper", text);
  }
  render(response) {
    const resultWrapper = document.querySelector("#response-wrapper");
    document.querySelector(".input-text").value = "";
    resultWrapper.innerHTML = response;
  }
}

const app = new App();
app.init();



๋‚˜๋Š” App.js ํŒŒ์ผ์˜ ์กด์žฌ ์ž์ฒด๋ฅผ ์žŠ๊ณ  ์žˆ์—ˆ๋‹ค.
์ด ํŒŒ์ผ์˜ fetch๋กœ ์š”์ฒญ์„ ๋ณด๋‚ด๊ณ  ๋ฐ›์•„์˜ค๋Š” ๊ฑด๋ฐ...!
์ค‘์š”ํ•œ ๋ถ€๋ถ„๋งŒ ์ž์„ธํžˆ ๋ณด์ž.

 post(path, body) {
    fetch(`http://localhost:4999/${path}`, {
      method: "POST",
      body: JSON.stringify(body),
      headers: {
        "Content-Type": "application/json",
      },
    })
      .then(res => res.json()
      )
      .then((res) => {
       this.render(res);
      });
  }

fetch๋กœ ์š”์ฒญ(์•ž์„œ ๋ณธ request)์„ ๋ณด๋‚ด๊ณ  ๊ทธ ๊ฒฐ๊ณผ๋Š” ์‘๋‹ต ๊ฐ์ฒด๋กœ, then์œผ๋กœ ๋ฐ›์•„์˜ฌ ์ˆ˜ ์žˆ๋‹ค.
then์— ๋‹ด๊ธด res๋Š” readablestream์„ ํฌํ•จํ•œ ์‘๋‹ต ๊ฐ์ฒด์ด๋‹ค. ๊ทธ๋ฆฌ๊ณ , ์ด res์— .json() ๋ฉ”์„œ๋“œ๋ฅผ ํ•ด์ค€๋‹ค.
res.json()์„ ํ•ด์ฃผ๋ฉด ์‘๋‹ต ๊ฐ์ฒด์˜ ๋ฐ”๋””๋งŒ ์ฝ์–ด json์—์„œ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๋ฐ์ดํ„ฐ๋กœ ๋ฐ”๊ฟ”์ค€๋‹ค(์—ญ์ง๋ ฌํ™”).
๊ทธ๋Ÿผ, ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์—์„œ ์ฝ์„ ์ˆ˜ ์žˆ๋Š” ๋ฐ์ดํ„ฐ๊ฐ€ ๋œ res๋Š” resnder ํ•จ์ˆ˜ ์•ˆ์œผ๋กœ ๋“ค์–ด๊ฐ€ ๋ธŒ๋ผ์šฐ์ €์— ๋ฟŒ๋ ค์ง„๋‹ค!




๋‹ค์‹œ ์š”์ฒญ์„ ๋ฐ›์•„ ๋ณด๋‚ด๊ณ , ์‘๋‹ต์„ ๋Œ๋ ค๋ณด๋‚ด then์œผ๋กœ ์‚ฌ์šฉํ•˜๋Š” ์ฝ”๋“œ๋ฅผ ๋ณด์ž.

const jsonParser = express.json({ strict: false });

app.post("/lower", jsonParser, function (req, res) {
  res.json(req.body.toLowerCase()); // ์—ฌ๊ธฐ์„œ res.json()์€ ์ง๋ ฌํ™” ๋ฉ”์„œ๋“œ
});
 .then(res => res.json() //์—ฌ๊ธฐ์„œ res.json์€ ์—ญ์ง๋ ฌํ™” ๋ฉ”์„œ๋“œ
      )
      .then((res) => {
       this.render(res);
       });

์ฃผ์˜ํ•ด์•ผํ•  ์ ์€, then์—์„œ res์— ํ•ด์ค€ .json์€ ์ง๋ ฌํ™”๊ฐ€ ์•„๋‹ˆ๋ผ, ์—ญ์ง๋ ฌํ™” ๋ฉ”์„œ๋“œ๋‹ค.
์•„๊นŒ๋Š” ์ง๋ ฌํ™”๋ผ๊ณ  ํ•˜๋”๋‹ˆ ์—ญ์ง๋ ฌํ™”๋ผ๋‹ˆ.








๐Ÿ“‚ res.json( )


์ด๋ฒˆ ๊ณผ์ œ์—์„œ ๋‚˜์˜จ json()๋ฉ”์„œ๋“œ๋Š” ๋‘ ์ข…๋ฅ˜๊ฐ€ ์žˆ๋‹ค.

  • Express์˜ res.json() : ์ง๋ ฌํ™”
  • fetch์˜ ์‘๋‹ต์„ ์‚ฌ์šฉํ•˜๋Š” .json(): ์—ญ์ง๋ ฌํ™”

 

๐Ÿ“Ž Express์˜ res.json() : ์ง๋ ฌํ™”

res.json([body])
Sends a JSON response. This method sends a response (with the correct content-type) that is the parameter converted to a JSON string using JSON.stringify().
The parameter can be any JSON type, including object, array, string, Boolean, number, or null, and you can also use it to convert other values to JSON.
https://expressjs.com/ko/api.html#res.json
res.json(null)
res.json({ user: 'tobi' })
res.status(500).json({ error: 'message' })





๐Ÿ“Ž fetch์˜ ์‘๋‹ต์„ ์‚ฌ์šฉํ•˜๋Š” .json(): ์—ญ์ง๋ ฌํ™”

ํ”„๋กœ๋ฏธ์Šค๊ฐ€ ๋ž˜ํ•‘ํ•˜๊ณ  ์žˆ๋Š” MIME ํƒ€์ž…์ด application/json์ธ HTTP ์‘๋‹ต ๋ชธ์ฒด๋ฅผ ์ทจ๋“ํ•˜๋ ค๋ฉด Response.prototype.json ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.
Response.prototype.json ๋ฉ”์„œ๋“œ๋Š” response ๊ฐ์ฒด์—์„œ HTTP ์‘๋‹ต ๋ชธ์ฒด๋ฅผ ์ทจ๋“ํ•˜์—ฌ ์—ญ์ง๋ ฌํ™” ํ•œ๋‹ค
๋ผ๊ณ  ํ•จ.
๋ชจ๋˜์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๋”ฅ๋‹ค์ด๋ธŒ 865ํŽ˜์ด์ง€
MDN Response.json() (https://developer.mozilla.org/en-US/docs/Web/API/Response/json)
Note that despite the method being named json(), the result is not JSON but is instead the result of taking JSON as input and parsing it to produce a JavaScript object.
์ด ๋ฉ”์„œ๋“œ๊ฐ€ json()์œผ๋กœ ๋ช…๋ช…๋˜์—ˆ์Œ์—๋„ ๋ถˆ๊ตฌํ•˜๊ณ  ๊ฒฐ๊ณผ๋Š” JSON์ด ์•„๋‹ˆ๋ผ JSON์„ ์ž…๋ ฅ์œผ๋กœ ๋ฐ›์•„๋“ค์ด๊ณ  ์ด๋ฅผ ๊ตฌ๋ฌธ ๋ถ„์„ํ•˜์—ฌ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๊ฒฐ๊ณผ์ด๋‹ค.
MDN

๋˜‘๊ฐ™์ด ์ƒ๊ฒผ๋Š”๋ฐ ์“ฐ์ž„์ด ์ •๋ฐ˜๋Œ€์—ฌ์„œ ํž˜๋“ค์—ˆ๋‹ค. ํ•˜์ง€๋งŒ ์ƒ๊น€์ƒˆ๋งŒ ๋‹ค๋ฅด๊ณ  ์“ฐ๋Š” ๋ฐฉ๋ฒ•, ์ƒํ™ฉ๋„ ๋‹ค๋ฅด๋‹ˆ ์ด์ œ ํ—ท๊ฐˆ๋ฆด ์ผ์€ ์—†์„ ๊ฒƒ์ด๋‹ค.







๐Ÿ“‚ mini node server์—์„œ ๋ฐ์ดํ„ฐ๊ฐ€ ์˜ค๊ณ ๊ฐ€๋Š” ๊ณผ์ •


fetch๋Š” ํ”„๋กœ๋ฏธ์Šค๋ฅผ ๋ฆฌํ„ดํ•œ๋‹ค.
fetch๊ฐ€ ๋ฆฌํ„ดํ•œ ํ”„๋กœ๋ฏธ์Šค๋Š” response ๊ฐ์ฒด๋ฅผ ๋ž˜ํ•‘ํ•˜๊ณ  ์žˆ๋‹ค.
์šฐ๋ฆฌ๋Š” response ๊ฐ์ฒด๊ฐ€ ๊ฐ€์ง„ ์‘๋‹ต ๋ชธ์ฒด๊ฐ€ ํ•„์š”ํ•˜๋‹ค.
response ๊ฐ์ฒด์˜ ์‘๋‹ต ๋ชธ์ฒด๋Š” MIME ํƒ€์ž…์ด application/json์ด๋‹ค.
fetch์— ์‚ฌ์šฉํ•˜๋Š” response.json() ๋ฉ”์„œ๋“œ๋กœ ์‘๋‹ต ๋ชธ์ฒด๋ฅผ ์ทจ๋“ํ•  ์ˆ˜ ์žˆ๋‹ค.
response.json()์€ ์‘๋‹ต ๊ฐ์ฒด์˜ ํ—ค๋”, ๋ฐ”๋””๋ฅผ ๋‹ค ๊ฐ€์ ธ์™€์„œ ๋ฐ”๋””๋งŒ ์ฝ๊ณ  ์—ญ์ง๋ ฌํ™” ํ•œ๋‹ค.
๋‹ค์‹œ ๋งํ•ด fetch๋กœ ๊ฐ€์ ธ์˜จ ํ”„๋กœ๋ฏธ์Šค๋ฅผ response.json()์œผ๋กœ ๋ฐ”๋””๋ฅผ ์—ญ์ง๋ ฌํ™” ํ•œ๋‹ค.
ํ”„๋กœ๋ฏธ์Šค์™€ ์—ญ์ง๋ ฌํ™”๋œ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๊ฐ์ฒด๋ฅผ ๋ฆฌํ„ดํ•จ!
์ด ์—ญ์ง๋ ฌํ™” ๋œ ๋ฐ์ดํ„ฐ๊ฐ€ App.js์˜ render() ํ•จ์ˆ˜๋กœ ๋“ค์–ด๊ฐ€์„œ ๋ธŒ๋ผ์šฐ์ €์— ๋ Œ๋”๋ง ๋œ๋‹ค.
------------------------------------------------------------------------------------------------------------------------
์„œ๋ฒ„์— req ๋ณด๋‚ผ ๋•Œ express.json() ์œผ๋กœ ๋ฐ”๋””๋ฅผ json์œผ๋กœ ํŒŒ์‹ฑํ•œ๋‹ค.
์„œ๋ฒ„๋Š” ๋ฐ”๋””๋ฅผ ๋ฐ›์•„์„œ ์›ํ•˜๋Š” ์‘๋‹ต์„ ์ค˜์•ผํ•˜๋Š”๋ฐ,
์‘๋‹ต ์—ญ์‹œ ์„œ๋ฒ„๋ฅผ ์ง€๋‚˜ ๋ธŒ๋ผ์šฐ์ €๋กœ ๋ณด๋‚ด์ง€๊ธฐ ๋•Œ๋ฌธ์—(์ •ํ™•ํžˆ๋Š” ํŽ˜์น˜๋ฅผ ํ†ตํ•ด ๋ฐ›๋Š” ํ”„๋กœ๋ฏธ์Šค ํ˜•ํƒœ์ด๋‹ค)
json ํ˜•ํƒœ๋กœ ๋ณด๋‚ด์•ผํ•œ๋‹ค.
๋ธŒ๋ผ์šฐ์ €์—์„œ๋Š” ํ”„๋กœ๋ฏธ์Šค ์•ˆ์— ์žˆ๋Š” ์‘๋‹ต ๋ชธ์ฒด๋ฅผ ๋ฐ›์•„ ์‚ฌ์šฉํ•ด์•ผํ•œ๋‹ค.
์—ฌ๊ธฐ์„œ, ๋ฐ›์•„์˜จ ์‘๋‹ต์„ response.json() ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•ด ์—ญ์ง๋ ฌํ™”๋œ ์‘๋‹ต ๋ชธ์ฒด (๋ฐ”๋””๋งŒ) ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.
์ด ๋ฐ”๋””(์—ญ์ง๋ ฌํ™”, JS ๋ฐ์ดํ„ฐ์ธ ์ŠคํŠธ๋ง ์ƒํƒœ)๋ฅผ render ํ•จ์ˆ˜ ์•ˆ์— ๋„ฃ์œผ๋ฉด ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ํ™”๋ฉด์— ์ถœ๋ ฅ์‹œํ‚จ๋‹ค.





Reference


SY
๋ชจ๋˜์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๋”ฅ๋‹ค์ด๋ธŒ
์ฝ”๋“œ์Šคํ…Œ์ด์ธ 

MDN
Express
https://cmang9.tistory.com/97
https://velog.io/@wonyuuu/JavaScript-JSON.parse-JSON.stringify