ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Day 12: 기본 오류 처리와 유효성 검사 추가
    21일오블완챌린지_vue.js와fastapi로 만드는 웹 주문 시스템 2024. 11. 18. 09:57

    오늘은 클라이언트와 서버에서 오류 처리유효성 검사를 강화하여 사용자 경험을 향상시키고, 잘못된 데이터가 입력되거나 전송되지 않도록 방지하겠습니다. 이를 통해 사용자는 입력 실수를 쉽게 파악하고, 서버에서도 예상치 못한 데이터를 처리하지 않도록 보호할 수 있습니다.


    1. 클라이언트 측 유효성 검사

    사용자가 데이터를 잘못 입력했을 때, 즉시 오류 메시지를 표시하여 문제를 수정할 수 있도록 합니다.

    OrderForm.vue 수정하기

    <template>
      <div class="order-form">
        <h2>주문하기</h2>
        <form @submit.prevent="submitOrder">
          <div>
            <label for="name">이름:</label>
            <input type="text" v-model="name" id="name" />
            <span v-if="errors.name" class="error">{{ errors.name }}</span>
          </div>
          <div>
            <label for="item">상품명:</label>
            <input type="text" v-model="item" id="item" />
            <span v-if="errors.item" class="error">{{ errors.item }}</span>
          </div>
          <div>
            <label for="quantity">수량:</label>
            <input type="number" v-model="quantity" id="quantity" min="1" />
            <span v-if="errors.quantity" class="error">{{ errors.quantity }}</span>
          </div>
          <div>
            <label for="notes">주문 메모:</label>
            <textarea v-model="notes" id="notes" placeholder="추가 요청 사항을 입력해 주세요"></textarea>
          </div>
          <button type="submit">주문 제출</button>
        </form>
        <div v-if="orderSubmitted" class="success-message">
          <h3>주문이 성공적으로 접수되었습니다!</h3>
        </div>
      </div>
    </template>
    
    <script>
    export default {
      name: "OrderForm",
      data() {
        return {
          name: "",
          item: "",
          quantity: 1,
          notes: "",
          orderSubmitted: false,
          errors: {
            name: null,
            item: null,
            quantity: null,
          },
        };
      },
      methods: {
        validateForm() {
          this.errors = { name: null, item: null, quantity: null };
          let isValid = true;
    
          if (!this.name.trim()) {
            this.errors.name = "이름을 입력해 주세요.";
            isValid = false;
          }
    
          if (!this.item.trim()) {
            this.errors.item = "상품명을 입력해 주세요.";
            isValid = false;
          }
    
          if (this.quantity < 1) {
            this.errors.quantity = "수량은 1 이상이어야 합니다.";
            isValid = false;
          }
    
          return isValid;
        },
        async submitOrder() {
          if (!this.validateForm()) {
            return;
          }
    
          const orderData = {
            name: this.name,
            item: this.item,
            quantity: this.quantity,
            notes: this.notes,
          };
    
          try {
            const response = await fetch("http://127.0.0.1:8000/order", {
              method: "POST",
              headers: {
                "Content-Type": "application/json",
              },
              body: JSON.stringify(orderData),
            });
    
            if (!response.ok) {
              throw new Error("서버 오류가 발생했습니다.");
            }
    
            const result = await response.json();
            console.log(result);
            this.orderSubmitted = true;
          } catch (error) {
            console.error("주문 전송 중 오류:", error);
            alert("주문 전송 중 문제가 발생했습니다. 다시 시도해 주세요.");
          }
        },
      },
    };
    </script>
    
    <style scoped>
    .order-form {
      max-width: 400px;
      margin: 20px auto;
      padding: 20px;
      border: 1px solid #ddd;
      border-radius: 5px;
    }
    .order-form div {
      margin-bottom: 10px;
    }
    .error {
      color: red;
      font-size: 0.9em;
    }
    .success-message {
      text-align: center;
      color: green;
    }
    </style>
    • validateForm 메서드: 사용자가 입력한 데이터를 클라이언트 측에서 확인하고, 유효하지 않은 경우 오류 메시지를 표시합니다.
    • errors 객체: 각 필드에 대한 오류 메시지를 저장하고 화면에 표시합니다.

    2. 서버 측 유효성 검사

    서버에서도 클라이언트가 잘못된 데이터를 전송했을 때 적절한 오류 메시지를 반환하도록 처리합니다.

    main.py 수정하기

    from fastapi import FastAPI, HTTPException
    from fastapi.middleware.cors import CORSMiddleware
    from pydantic import BaseModel, Field
    from typing import List, Optional
    
    app = FastAPI()
    
    # CORS 설정
    app.add_middleware(
        CORSMiddleware,
        allow_origins=["http://localhost:5173"],  # Vue.js가 실행 중인 포트
        allow_credentials=True,
        allow_methods=["*"],
        allow_headers=["*"],
    )
    
    # 주문 데이터 구조 정의
    class Order(BaseModel):
        name: str = Field(..., min_length=1, description="이름은 필수입니다.")
        item: str = Field(..., min_length=1, description="상품명은 필수입니다.")
        quantity: int = Field(..., ge=1, description="수량은 1 이상이어야 합니다.")
        notes: Optional[str] = None
    
    # 임시로 주문을 저장할 리스트
    orders: List[Order] = []
    
    # 주문 접수 엔드포인트
    @app.post("/order")
    async def create_order(order: Order):
        if len(order.name.strip()) == 0 or len(order.item.strip()) == 0:
            raise HTTPException(status_code=400, detail="이름과 상품명은 필수입니다.")
        if order.quantity < 1:
            raise HTTPException(status_code=400, detail="수량은 1 이상이어야 합니다.")
        
        orders.append(order)  # 주문 데이터를 리스트에 저장
        return {"message": "Order received", "order": order}
    
    # 모든 주문 조회 엔드포인트
    @app.get("/orders")
    async def get_orders():
        return {"orders": orders}
    • Field를 통한 유효성 검사: pydantic의 Field를 사용하여 서버에서 유효성을 검사합니다.
    • HTTPException: 클라이언트가 잘못된 데이터를 보낼 경우, 400 상태 코드를 반환하며 적절한 오류 메시지를 제공합니다.

    3. 테스트하기

    1. 클라이언트에서 필드가 비어 있는 상태로 제출하거나, 수량이 0 이하로 입력된 경우 오류 메시지가 표시되는지 확인합니다.
    2. 서버 측에서 유효하지 않은 데이터가 전송되었을 때 400 상태 코드와 함께 적절한 오류 메시지가 반환되는지 테스트합니다.

    4. 오늘의 마무리

    오늘은 클라이언트와 서버 모두에서 오류 처리와 유효성 검사를 강화하여 잘못된 데이터 입력 및 전송을 방지하는 방법을 배웠습니다. 내일은 CSS 또는 CSS 프레임워크를 사용하여 기본 스타일링을 개선하여 더 보기 좋은 사용자 인터페이스를 만들어 보겠습니다.

Designed by Tistory.