inblog logo
|
LifeLog, DevLog
    Web

    REST API

    KYJTHEYJ's avatar
    KYJTHEYJ
    Nov 24, 2025
    REST API
    Contents
    API를 왜 사용해야하는가?REST API 명세 및 작성명세 결론 정리실 사용 예시실전 팁

    API를 왜 사용해야하는가?

    • 프론트와 백엔드의 분리

      • 프론트는 디자인, 백엔드는 데이터 처리를

      • 각자 독립적 개발이 가능하고 후에 API를 통해 연동

    • 데이터 검증 및 제공의 편리성

      • 잘못된 응답 제공 될 경우 거부 가능

      • 데이터 제공시 가공 가능

    • 같은 기능 사용

      • 다양한 클라이언트의 환경에서 같은 API 제공 가능

    REST API 명세 및 작성

    • URL은 자원을 표현해야함

      • 사용자 목록을 조회하는 경우

        • GET /users → ✅

        • GET /getUsers → ❌, /user/show/users → ❌ (URL에 동사가 포함)

      • 삭제의 경우

        • DELETE /users/test → ✅

        • DELETE /users?id=test → ❌ (자원의 명시가 쿼리 스트링)

    • HTTP 메서드로 행위를 표현해야함

      • GET → 조회

      • POST → 생성

      • PUT → 전체 수정

      • PATCH → 부분 수정

      • DELETE → 삭제

    • 계층 구조의 표현

      • GET /users/123/posts → 123번 사용자의 게시글

    • 응답은 일관성을 유지해야함

      • 성공 응답과 에러시 실패 응답은 기본적으로 일관성을 유지해야함

        • 예시를 들어, success와 message 라는 내부 조건 검토 필드를 성공에만
          넣어놓고 실패시 message만 보내는 것은 잘못된 것임

      명세 결론 정리

      • 동사 보다 명사, 단수보다 복수

      • 마지막에 / 사용하지 않기

      • _ 대신 - 사용하기

      • 확장자 넣지 않기

      • 계층화 하기

        /items/{memberId}/members/{itemId} // 잘못됨!
        
        /members/{memberId}/items/{itemId} // 올바른 계층 구조!

    실 사용 예시

    // 사용자 목록 조회
    app.get('/api/users', async (req, res) => {
      try {
        const users = await User.findAll();
        res.status(200).json({
          success: true,
          data: users
        });
      } catch (error) {
        res.status(500).json({
          success: false,
          message: '서버 오류'
        });
      }
    });
    
    // 특정 사용자 조회
    app.get('/api/users/:id', async (req, res) => {
      try {
        const user = await User.findById(req.params.id);
        if (!user) {
          return res.status(404).json({
            success: false,
            message: '사용자를 찾을 수 없습니다'
          });
        }
        res.status(200).json({
          success: true,
          data: user
        });
      } catch (error) {
        res.status(500).json({
          success: false,
          message: '서버 오류'
        });
      }
    });
    
    // 사용자 생성
    app.post('/api/users', async (req, res) => {
      try {
        const { name, email, password } = req.body;
        
        // 유효성 검증
        if (!email || !password) {
          return res.status(400).json({
            success: false,
            message: '필수 항목을 입력해주세요'
          });
        }
        
        const newUser = await User.create({ name, email, password });
        res.status(201).json({
          success: true,
          data: newUser
        });
      } catch (error) {
        res.status(500).json({
          success: false,
          message: '서버 오류'
        });
      }
    });
    
    // 사용자 수정
    app.patch('/api/users/:id', async (req, res) => {
      try {
        const { name, email } = req.body;
        const user = await User.findByIdAndUpdate(
          req.params.id,
          { name, email },
          { new: true } // 수정된 데이터 반환
        );
        
        if (!user) {
          return res.status(404).json({
            success: false,
            message: '사용자를 찾을 수 없습니다'
          });
        }
        
        res.status(200).json({
          success: true,
          data: user
        });
      } catch (error) {
        res.status(500).json({
          success: false,
          message: '서버 오류'
        });
      }
    });
    
    // 사용자 삭제
    app.delete('/api/users/:id', async (req, res) => {
      try {
        const user = await User.findByIdAndDelete(req.params.id);
        
        if (!user) {
          return res.status(404).json({
            success: false,
            message: '사용자를 찾을 수 없습니다'
          });
        }
        
        res.status(200).json({
          success: true,
          message: '삭제되었습니다'
        });
      } catch (error) {
        res.status(500).json({
          success: false,
          message: '서버 오류'
        });
      }
    });

    실전 팁

    • 버전 관리를 명세

      • /…/v1/users → 해당 버전을 v1으로 명세

    • 아래의 구성요소를 갖고 있어야 좋은 명세서

      구성 요소

      설명

      API 개요

      이 API가 어떤 목적으로 만들어졌는지, 버전 정보, 전체 주소(Base URL) 등

      Endpoint

      API가 제공하는 개별 기능의 '주소' (URI)

      Method

      해당 주소로 어떤 작업을 할지 결정 (HTTP Method)

      Parameters

      요청할 때 꼭 보내야 하는 추가 정보들

      Request Body

      생성하거나 수정할 데이터의 실체 (주로 JSON 형식)

      Response

      요청 처리 후 서버가 돌려주는 응답 정보

      Status Codes

      요청의 성공/실패 여부를 나타내는 숫자 코드

    Share article
    Contents
    API를 왜 사용해야하는가?REST API 명세 및 작성명세 결론 정리실 사용 예시실전 팁

    LifeLog, DevLog - https://github.com/KYJTHEYJ

    RSS·Powered by Inblog