에러: req.write() chunk 잘림

·2024년 5월 19일

main에서 바로 review_db 마이크로서비스로 접근하던 코드를 controller 역할을 하는 review 마이크로서비스를 통해 접근하도록 수정해주던 중 문제가 발생했다.

기존 main 마이크로서비스에서 review_db에 요청을 보내는 부분

//후기 추가 DB 반영
  creatingReview: (req, res) => {
    const username = res.locals.auth;

    /* msa */
    const postOptionsResident = {
      host: 'stop_bang_auth_DB',
      port: process.env.MS_PORT,
      path: `/db/resident/findById`,
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      }
    };
    const requestBody = {username};
    httpRequest(postOptionsResident, requestBody)
      .then(res => {
        const postOptions = {
          host: 'stop_bang_review_DB',
          port: process.env.MS_PORT,
          path: `/db/review/create`,
          method: 'POST',
          headers: {
            'Content-Type': 'application/json',
          }
        }
        const requestBody = {
          ...
          req.body,
          r_id: res.body[0].id,
          ra_regno: req.params.ra_regno,
        }
        return httpRequest(postOptions, requestBody);
      })
      .then(() => {
        return res.redirect(`/realtor/${req.params.ra_regno}`);
      });
  },

수정한 main마이크로서비스
//후기 추가 DB 반영
  creatingReview: (req, res) => {
    // const username = res.locals.auth;
    // const id = res.locals.id;

    /* msa */
    const postOptions = {
      host: 'stop_bang_review',
      port: process.env.MS_PORT,
      path: `/review/${req.params.sys_ra_regno}/create_process`,
      method: 'POST',
      headers: {
        ...
        req.headers,
        auth: res.locals.auth,
        id: res.locals.id
      }
    };
    const body = req.body;
    httpRequest(postOptions, body)
      .then(() => {
        return res.redirect(`/realtor/${req.params.sys_ra_regno}`);
      });
  },

작성한 review정보가 담긴 req.body를 review마이크로서비스에 body로 보낸다.


⬆️ main의 request를 받아서 reveiw_db에 리뷰 생성 요청을 보내는 reveiw 마이크로서비스

⬆️ review_db에 sequelize를 이용해 실제로 데이터를 생성하는 review_db 마이크로서비스





그런데! req.body에 필요한 값을 잘 담아 보냈음에도 db에 description과 rate 데이터가 비정상적으로 저장되는 것을 확인할 수 있다.


main에서는 description까지 request의 body로 모두 잘 가져오고 있음.


main 마이크로서비스에서 review마이크로서비스로 넘어오면서 req.body가 잘린 것을 확인할 수 있다.


왜 이런 일이 발생하지?

일단 httpRequest 메소드의 내용은 아래와 같다.

module.exports = {
  httpRequest: (params, body) => {
    return new Promise(function (resolve, reject) {
      const clientRequest = http.request(params, incomingMessage => {
        // Response object.
        let response = {
          statusCode: incomingMessage.statusCode,
          headers: incomingMessage.headers,
          body: []
        };

        // Collect response body data.
        incomingMessage.on('data', chunk => {
          response.body.push(chunk);
        });

        // Resolve on end.
        incomingMessage.on('end', () => {
          if (response.body.length) {

            response.body = response.body.join();

            try {
              response.body = JSON.parse(response.body);
            } catch (error) {
              // Silently fail if response is not JSON.
            }
          }

          resolve(response);
        });
      });
      
      // Reject on request error.
      clientRequest.on('error', error => {
        reject(error);
      });

      clientRequest.on('close', () => {
        console.log('Sent message to microservice.');
      });

      // Write request body if present.
      if (body) {
        clientRequest.write(JSON.stringify(body));
        
      }

      // Close HTTP connection.
      clientRequest.end();
    });
  }
}

console을 찍어보니 JSON.stringify(body)에서는 잘림 없이 변환된다.

그렇다면 write 메소드에 문제가 있는 것 같다.
공식문서를 살펴보자.
https://nodejs.org/api/http.html#requestwritechunk-encoding-callback

Sends a chunk of the body. This method can be called multiple times. If no Content-Length is set, data will automatically be encoded in HTTP Chunked transfer encoding, so that server knows when the data ends.

The Transfer-Encoding: chunked header is added. Calling request.end() is necessary to finish sending the request.

The encoding argument is optional and only applies when chunk is a string. Defaults to 'utf8'.


해결

 headers: {
        ...
        req.headers,
        auth: res.locals.auth,
        id: res.locals.id
      }

이 부분을

headers : 
	'Content-Type': 'application/json'

이렇게
헤더 설정이 application/json으로 설정했더니 해결됨.


profile
🔥

0개의 댓글