express.Router()를 사용해 특정 경로에 대한 라우팅과 핸들러를 정의
- routes 폴더를 만들어 각 경로에 대한 api 만들기
res.send의 오류
: 원래 모든 응답을 res.send를 보내게 코딩을 했다. 하지만 post와 같은 요청을 하는 경우 postman에선 오류를 반환했다.
gpt 답변
- res.send()
- 유연한 응답 형식: 문자열, 객체, 배열 등 다양한 데이터를 클라이언트에 보낼 수 있습니다.
- 자동으로 JSON 변환: 객체나 배열을 전달할 때는 자동으로 JSON 형식으로 변환해주지만, 명확하게 JSON 형식을 보장하는 것은 아닙니다.
- 응답의 Content-Type: 객체를 보낼 때 Content-Type이 application/json으로 설정되지만, 문자열을 보낼 때는 text/html로 설정됩니다.
- res.json()
- JSON 전용: 객체나 배열을 JSON 형식으로 명확하게 클라이언트에 보냅니다.
- 일관된 Content-Type: 항상 application/json으로 Content-Type 헤더를 설정하여 클라이언트에 JSON 응답임을 명확히 합니다.
- 보안 측면: Express 4.x 이후 버전에서는 res.json()을 사용할 때 JSON 데이터의 끝에 **\n**를 추가하는데, 이는 보안상의 문제를 줄이기 위한 조치입니다.
왜 res.send()에서 에러가 발생했을까?
- Postman에서 API를 테스트할 때 클라이언트는 JSON 형식을 기대하는 경우가 많음
- res.send()로 문자열 응답을 보내거나, 데이터가 JSON으로 명확히 변환되지 않았을 경우
- Content-Type이 text/html로 설정될 수 있어 Postman에서 JSON 파싱 오류가 발생 가능성이 있음
언제 res.json()을 사용해야 할까?
- API 요청이 JSON 데이터를 주고받는 상황에서는 res.json()을 사용하는 것이 더 안전
- SON 형식을 일관되게 유지해 주고, Content-Type도 자동으로 application/json으로 설정되기 때문
routes 폴더
- routineRoutes.js 파일
const express = require("express");
//express.Router()를 사용해 경로별 핸들러를 정의
const router = express.Router();
router.use(express.json());
router.get("/", (req, res) => {
res.json("루틴 페이지 : 전체 조회");
});
//res.send 사용 시 오류 발생
router.post("/", (req, res) => {
res.json("루틴 페이지 : 새로운 루틴 추가");
});
router.put("/:id", (req, res) => {
res.json("루틴 페이지 : 특정 루틴 수정");
});
router.delete("/:id", (req, res) => {
res.json("루틴 페이지 : 특정 루틴 삭제");
});
//모듈 내보내기
module.exports = router;
- userRoutes.js
const express = require("express");
const router = express.Router();
router.use(express.json());
//유저 정보 조회
router.get("/:id", (req, res) => {
res.json("유저 정보 조회");
});
//회원가입
router.post("/join", (req, res) => {
res.json("회원가입");
});
//로그인
router.post("/login", (req, res) => {
res.json("로그인");
});
module.exports = router;
- statsRoutes.js
const express = require("express");
const router = express.Router();
router.use(express.json());
//날짜별
//루틴별
//쿼리스트링으로 받아
router.get("/", (req, res) => {
res.json("완료 루틴 통계");
});
module.exports = router;
- completeRoutes.js
const express = require("express");
//express.Router()를 사용해 경로별 핸들러를 정의
const router = express.Router();
router.use(express.json());
//날짜별?
//아래 루틴별 완료 기록 조회랑 합치기
//쿼리스트링을 사용할 경우 콜백함수 내부에서 if문으로 처리
//아니면 /:id 와 같이 url을 바꿔야함
router.get("/", (req, res) => {
res.json("루틴 완료 기록 : 전체 조회");
});
//루틴별 완료 기록 조회
//쿼리스트링으로 루틴의 종류를 받을 예정
///completion?categoryId=카테고리ID (그냥 루틴 아이디 받으면 될 듯)
//const categoryId = req.query.categoryId (값 받아오기 예)
router.get("/", (req, res) => {
let routineId = req.query.routineId;
res.json("루틴 완료 기록 : 루틴별 조회");
});
//여기도 쿼리스트링으로 기록 id 랑 날짜 받으면 될듯
router.post("/", (req, res) => {
res.json("루틴 완료 기록 : 기록하기");
});
router.put("/:id", (req, res) => {
res.json("루틴 완료 기록 : 수정하기");
});
module.exports = router;
주석 처리를 해두었지만, url 쿼리 스트링이 고민이다.
짜다보니 조회 get의 경우 숨겨서 보낼 요청은 없으니, 쿼리스트링을 사용해야할 것 같다.
그럼 if문을 사용해야하는데, 코드가 길어질 듯하다. 일단 짜보고 나중에 반복되는 부분을 처리해야 겠다..
근데 사용자에 따라 다른 데이터를 가져와야 하는데, 그럼 사용자 아이디는 요청 body로 보내고, 날짜나 카테고리는 쿼리 스트링으로 받는 건가..? 복잡해질 것 같은데,,,
--> gpt한테 물어봄 (나중에 구현할때 참고해야지)
네, 맞습니다! 사용자 정보는 **요청 본문(Request Body)**으로 받고, 필터링 정보는 **쿼리 스트링(Query String)**으로 전달받아, 이를 조합하여 사용자별로 필터링된 데이터를 가져오는 방식으로 처리하면 됩니다.
이 방식은 보안과 유연성 면에서 모두 효율적입니다. 사용자 정보는 민감한 데이터이므로 Request Body를 통해 안전하게 받고, 필터링 정보는 URL에 포함할 수 있는 간단한 쿼리 스트링으로 받아 요청에 따라 다양한 데이터 조합을 지원할 수 있습니다.
예시 코드
- 사용자 정보는 요청 본문으로 받고
- 필터링 정보는 쿼리 스트링으로 받는 구조를 만들어 보겠습니다.
// 예시 라우트
app.post("/api/data", (req, res) => {
const user = req.body.user; // 사용자 정보는 요청 본문에서 받음
const filter = req.query.filter; // 필터 정보는 쿼리 스트링에서 받음
// 사용자 정보와 필터링 정보가 제대로 전달됐는지 확인
console.log("User:", user);
console.log("Filter:", filter);
// 사용자 정보에 따라 데이터를 필터링하는 로직 작성
let data = getDataForUser(user); // 예시 데이터 로직
if (filter) {
data = applyFilter(data, filter); // 필터 적용 (예시)
}
res.json({ data });
});
// 데이터 로직 예시
function getDataForUser(user) {
// DB 조회 또는 로직을 통해 사용자별 데이터 가져오기
return [
{ id: 1, category: "운동", activity: "조깅" },
{ id: 2, category: "독서", activity: "책 읽기" },
];
}
function applyFilter(data, filter) {
// 필터링 로직 적용
return data.filter((item) => item.category === filter);
}
요청 예시
1. 사용자 정보와 함께 전체 데이터 조회
POST /api/data
Content-Type: application/json
Body: { "user": "user123" }
2. 사용자 정보와 특정 필터 조건으로 데이터 조회
POST /api/data?filter=운동
Content-Type: application/json
Body: { "user": "user123" }
이렇게 설정하면 Request Body로 사용자 정보를 받고, 쿼리 스트링으로 필터 조건을 전달받아 조건에 맞는 데이터를 제공합니다.
추가적인 질문이 있으면 언제든지 말씀해 주세요! 😊
'프로젝트 > 아침 루틴' 카테고리의 다른 글
회원가입 없이 서비스 이용하기 (기록하기) / uuid, cookie-parser 예제 정리까지 (0) | 2024.11.02 |
---|---|
DB 설정하고 MySQL connection pool 사용하기 / try-catch와 비동기 고민 (0) | 2024.11.01 |
server.js/ app.js 로 파일 분리하기 (0) | 2024.10.29 |
초기 설정 package.json , express, .env (0) | 2024.10.29 |