[Node.js] Express 서버에서 JSON 형태로 응답하기

9
post-thumbnail
post-custom-banner

삽질의 시작💬

  • express server를 Express-generator라는 패키지를 통해 구현하였다.express를 하나씩 세팅하려면 패키지, 폴더 구조까지 고려해야할 사항이 많은데, 똑똑한 generator덕에 프레임워크에 필요한 pakage.json과 기본 구조까지 아주 멋지게 잡아서 생성되었다.

  • 하지만.. express의 지식이 없는 나에게 Express-generator가 만든 express 서버는 Welcome to Express라는 index 화면만 바라보게할 뿐.. 감히 건드릴 수 없는 존재였다!

    나의 첫 express 서버..멋지구만..🙂

  • 이와 더불어 내가 Parcel을 통해 화면을 보여주고 있는 서버와, json 데이터를 가져올 서버는 아예 다른 서버인데, fetch API로 어떻게 데이터를 요청할 수 있을지 정말 막막했다.


  • 그럼 Express-generator가 만든 각 폴더, 파일은 왜 만들어졌으며 어떤 원리로 서버가 돌아가는 걸까? 하는 의문이 생겼다.

Express-generator로 만든 express 서버 구조(MVC 모델)

  • bin/www: http 모듈로 서버를 등록하고 에러 핸들링을 하는 듯 실제 활동을 제어하는 중요한 곳. package.json scripts를 확인해보면 서버가 시작될 때 이 bin/www 파일이 실행되도록 설정되어 있는 것을 확인할 수 있다.
  • app.js: 서버에서 사용할 미들웨어를 정의하는 곳
  • public 폴더: javascript, css 등 정적인 파일이 있는 곳
  • routes 폴더: 미들웨어에서 등록될 라우터들이 있는 곳 client의 요청에 응답 처리(라우팅)를 하는 파일이 있다.
  • views: 초기에 설정한 언어로 구현된 view 템플릿을 담고 있는 곳(ejs, pug 등)

미들웨어의 역할

  • 모든 코드를 실행.
  • 요청 및 응답 오브젝트에 대한 변경을 실행.
  • 요청-응답 주기를 종료.
  • 스택 내의 그 다음 미들웨어를 호출.

Client 서버에서 express 서버로 요청을 보내보자

  • express 서버에서 요청을 받은 후 응답을 하려면 client의 요청을 get해서 응답을 보내줘야 한다.

  • 나는 client 서버에서 '/image'로 요청할 것이기에 미들웨어에 '/image' 요청을 받을 라우터를 등록해서 요청을 처리하는 방식으로 구현하였다.

1) image 라우터를 생성한다.

//image.js
const express = require("express");
const router = express.Router();

router.get("/", (req, res, next) => {
  res.json([{ id: 1, username: "daisy" }]);
});

module.exports = router;

2) 미들웨어에 image라우터를 선언해준다.

const imageRouter = require("./routes/image");

3) "/image"요청이 왔을 때 image라우터가 GET 요청을 처리할 수 있게 use 메서드를 사용해준다.

//미들웨어
app.use("/image", imageRouter);

4) client의 main.js에서 express에 요청을 한다.

const promise = fetch("http://localhost:3000/image")
.then(response => console.log(response));

5) client 서버와 express 서버를 실행시켜서 응답 결과를 확인해본다.


CORS 에러

  • 오잉? 에러가 떴다. 당연히 내가 코드를 잘못 작성해서 나오는 에러이겠거니~ 하고 계속 코드를 수정했다. 그런데도 저 오류가 계속 나타나길래, 도대체 오류에서 말하는 CORS가 무엇인지 찾아봤다.😱

    *CORS : Cross-Site Http Request를 가능하게하는 표쥰 규약이다.
    웹브라우저가 XMLHttpRequest나 Fetch API로 외부서버의 데이터에 접근하려는 경우, 보안 상의 이유로, 브라우저는 CORS를 제한하고 있다.

프록시를 추가해주거나 헤더에 어떤 문구를 추가해주는 방법도 있지만, 이 문제는 express의 CORS 미들웨어를 이용해서 쉽게 해결할 수 있다고 한다.(다행이다..🥶)

const express = require('express');
const cors = require('cors'); //CORS 미들웨어 객체 선언
const app = express();

app.use(cors());// CORS 미들웨어 등록
  • $ npm install cors로 설치 후 미들웨어에 위에 있는 코드를 삽입 후 client 서버를 다시 실행시켜 보았다.

  • response 객체를 console에 찍어보니 아래와 같은 결과가 나왔다.

  • 뭘까..? 값이 들어왔다는 걸까? 일단 status가 200으로 뜨는 거 보면 가져온거 같은데..

  • Network탭에서 Response 결과를 보니 내가 express에서 보낸 json 객체가 있었다.👏👏

//image 라우터
const promise = fetch("http://localhost:3000/image")
  .then(response => response.json())
  .then(json => console.log(json));
  • response json을 콘솔에 찍어보기 위해 image 라우터를 위와 같이 수정해줬다.
  • 응답 결과가 정상적으로 출력되었다.

json file을 보내보자!

그럼 실제 json 파일을 응답 객체로 넘겨보자.

//image 라우터
const express = require("express");
const router = express.Router();
const fs = require("fs");
const data = JSON.parse(fs.readFileSync("./public/data/response.json", "utf8"));

router.get("/", (req, res, next) => {
  res.json(data);
});

module.exports = router;
  • fs.readFileSync를 이용해서 local에 있는 json파일을 동기적으로 읽어온 뒤 JSON.parse()를 통해 객체로 생성하여 data 변수에 넣어주었다.
  • 이후 res.json(data)을 통해 client 서버 요청에 대한 응답으로 json 객체를 보내주었다.

client에서 fetch API로 값을 받아와 console에 출력해보았다. 성공이다!!! 👏👏👏

참고

post-custom-banner

10개의 댓글

comment-user-thumbnail
2021년 2월 24일

너무 감사합니다 ㅠㅠ cors 무시하고 있다가 데이지님 글보고 해결합니다........

1개의 답글
comment-user-thumbnail
2021년 2월 25일

데이지 감사해요~~!! 화면까지 자세하게 기록해주신 덕분에 엄청엄청 도움 많이 받고가요ㅎㅎ👍🌷

1개의 답글
comment-user-thumbnail
2021년 2월 25일

데이지 정리 천재인것같아요 ㅠ.ㅠ 이제야 감이 잡히는 느낌이에요..✨

1개의 답글
comment-user-thumbnail
2021년 2월 26일

새로운 라이브서버에서 fetch를 연습하던 중에 cor 에러는 어떻게 해결하나 궁금했는데 감사합니다~

1개의 답글
comment-user-thumbnail
2021년 2월 26일

진짜 너무너무너무너무너무너무너무너무너무x9999999999999999999999999
감사합니다 데이지 짱이에요

1개의 답글