✨ 새로운 API 만들기

Yeonn·2024년 10월 29일
0

Backend 👀

목록 보기
4/10
post-thumbnail

🌱 폴더 구조

your-project
├── src
│   ├── app.js                // Express 앱 설정, 미들웨어 및 라우터 연결
│   ├── index.js              // 서버의 엔트리 포인트, 서버 실행 코드 포함
│   ├── config     
│   │   └── db.js             // MongoDB 연결 설정
│   ├── models                // 데이터베이스 스키마 및 모델 폴더
│   │   └── Post.js           // 예시 Mongoose 스키마 및 모델 파일
│   └── routes                // API 라우터 폴더
│       └── postsRouter.js    // "/api/posts" 라우트를 처리하는 라우터 파일
├── .env                      // 환경 변수 파일
├── package.json              // 프로젝트 설정 및 종속성 파일
├── nodemon.json              // Nodemon 설정 파일
└── babel.config.json         // Babel 설정 파일

새로운 API 만들기

✔️ Express 설치 및 기본 설정

npm init -y
npm install express

// package.json 설정
"start": "node src/index.js"      // Scripts 추가
"type": "module"                  // Type 설정

✔️ .env 파일 설정 (환경 변수 사용)

PORT=8080
MONGO_URI=your_mongodb_url

✔️ 주요 패키지 설치

npm install express mongoose dotenv
npm install --save-dev nodemon @babel/core @babel/node @babel/preset-env
  • dotenv: 환경 변수 관리
  • mongoose: MongoDB와의 연결 및 스키마 관리
  • nodemon: 서버 자동 재시작
  • @babel: ES6+ 코드 지원

✔️ 설정 파일 작성

  • babel.config.json
    {
      "presets": ["@babel/preset-env"]
    }
  • nodemon.json
    {
      "watch": ["src/*"],
      "ext": "js ts json",
      "exec": "babel-node ./src/index.js",
      "verbose": true,
      "ignore": ["*.test.js", "node_modules"],
      "delay": 1500,
      "env": {
        "NODE_ENV": "development",
        "PORT": 8080
      }
    }

❓ 파일별 기본 코드

✔️ index.js

  • 서버의 엔트리 포인트로 app.js를 불러와 서버를 실행
import app from './app.js';

const PORT = process.env.PORT || 8080;
app.listen(PORT, () => {
  console.log(`Server listening on port ${PORT}`);
});

✔️ app.js

  • Express 애플리케이션을 생성
  • 미들웨어와 라우터를 연결
import express from 'express';
import dotenv from 'dotenv';
import usersRouter from './routes/usersRouter.js';

dotenv.config();
const app = express();

app.use(express.json()); // JSON 요청 본문 파싱
app.use('/api/users', usersRouter);

// 에러 핸들링 미들웨어
app.use((err, req, res, next) => {
  console.error(err.stack);
  res.status(500).send({ message: 'Something broke!' });
});

export default app;

✔️ db.js

  • MongoDB 연결 설정
import mongoose from 'mongoose';
import dotenv from 'dotenv';

dotenv.config();

mongoose.connect(process.env.MONGO_URI, { useNewUrlParser: true, useUnifiedTopology: true });

const database = mongoose.connection;
database.on('error', (err) => console.log('Database Error!', err));
database.once('open', () => console.log('DB connected'));

✔️ routes/usersRouter.js

import { Router } from 'express';

const usersRouter = Router();

usersRouter.get('/', (req, res) => res.send('get all users'));
usersRouter.post('/', (req, res) => res.send('create user'));
usersRouter.put('/:id', (req, res) => res.send('edit user'));
usersRouter.delete('/:id', (req, res) => res.send('delete user'));

export default usersRouter;

✔️ models/schema.js

  • Mongoose Schema 설정
import mongoose, { Schema } from 'mongoose';

const PostSchema = new Schema(
  {
    title: { type: String, required: true },
    content: { type: String, required: true }
  },
  { timestamps: true }
);

const Post = mongoose.model('Post', PostSchema);

export default Post;

❓ Request Handler

🌱 요청을 처리하는 콜백 함수

✔️ req

  • req.params: Path Parameter에 접근할 수 있는 프로퍼티
  • req.queries: Query String에 접근할 수 있는 프로퍼티
  • req.body: POST, PUT 요청에 Body에 접근할 수 있는 프로퍼티
  • req.get(): 요청의 HTTP Header 값을 조회할 수 있는 프로퍼티
    /api/users/:id  // -> Path Parmeter: req.params.id
    /api/posts?page=2&size=10 // -> req.queries: req.query.page, req.query.size
    /req.get('Authorization') // -> req.get()

✔️ res

  • res.send(): text 형식의 HTTP 응답 전송
  • res.json(): JSON 형식의 HTTP 응답 전송
  • res.render(): HTML Template을 사용하여 화면을 전송
  • res.set(): 응답의 HTTP Header를 전송
  • res.status(): 응답의 HTTP Status Code를 설정
    res.stauts(404).send('User not found');

❓ CRUD 예시

✔️ Create

usersRouter.post('/', async (req, res) => {
  const { title, content } = req.body;
  try {
    await Post.create({ title, content });
    res.send('Post Successfully Created');
  } catch (err) {
	  console.error(`Error creating post: ${err.message}`);
	  res.status(500).send('Server Error');
}
});

✔️ Read

usersRouter.get('/', async (req, res) => {
  try {
    const allPosts = await Post.find({});
    res.json(allPosts);
  } catch (err) {
    console.error(`Error Reading post: ${err.message}`);
	  res.status(500).send('Server Error');
}
});

✔️ Update

usersRouter.put('/:id', async (req, res) => {
  const { id } = req.params;
  const { title, content } = req.body;
  try {
    const updatedPost = await Post.findByIdAndUpdate(id, { title, content }, { new: true });
    if (!updatedPost) return res.status(404).send('Post not found');
    res.json(updatedPost);
  } catch (err) {
    console.error(`Error Updating post: ${err.message}`);
	  res.status(500).send('Server Error');
  }
});

✔️ Delete

usersRouter.delete('/:id', async (req, res) => {
  const { id } = req.params;
  try {
    const deletedPost = await Post.findByIdAndDelete(id);
    if (!deletedPost) return res.status(404).send('Post not found');
    res.json(deletedPost);
  } catch (err) {
    console.error(`Error Deleting post: ${err.message}`);
	  res.status(500).send('Server Error');
  }
});

0개의 댓글