jun-wiki

View My GitHub Profile

Posts (Latest 10 updated) :
Read all
Contents:
  1. 공부 시작
    1. docker 명령어
    2. 기본 설정?
      1. 간단 설명
      2. DB->HTML 까지 요청~응답 흐름
    3. 환경 한눈에
    4. 순서
      1. 1-1 브라우저 -> Vite dev 서버
      2. 1-2 React 앱 -> 백엔드 호출
      3. 1-3 Uvicorn(ASGI 서버) → FastAPI(라우팅)
      4. 1-4 Motor(비동기 드라이버) → MongoDB
      5. 1-5 MongoDB → FastAPI → 브라우저
      6. 2-1 React 폼 전송
      7. 2-2 FastAPI: 라우팅 + Pydantic 검증
      8. 2-3 React 후처리
    5. 요소들 역할 정리

공부 시작

뭐부터 해야할지 일단 머리부터 박아봤다

일단 docker 빌드해서 초기 환경 설정하고 이것저것 프레임워크 까는 거 부터 시작하자

…

짧은 팀 회의 후 기술 스택 선정 했으니 이것 위주로 공부 해야한다

CSS - Tailwind

프론트엔드 - React

백엔드 - FastAPI

DB - MongoDB

인프라 - AWS


docker 명령어

  • 상태 확인

    • docker compose ps
  • 로그 보기

    • docker compose logs -f --tail=100 frontend
      docker compose logs -f backend
      
  • 일시정지

    • docker compose stop
  • 다시시작

    • docker compose up -d
  • 완전 종료

    • docker compose down
  • 데이터까지 클리어

    • docker compose down -v
  • 개별 서비스 제어

    • docker compose stop frontend
      docker compose up -d frontend
      docker compose restart backend
      docker compose rm -f frontend   # 컨테이너 제거(정지 필요)
      
  • 이미지 다시 빌드

    • docker compose up -d --build          # 전체 재빌드
      docker compose up -d --build frontend # 프론트만 재빌드
      


기본 설정?

도커로 일단 초기 설정부터 해볼 계획이다

간단 설명

  • Docker = 실행 환경 보장

  • React + Tailwind = 브라우저에서 쓸 UI

  • FastAPI = 요청 받아 DB로부터 JSON 돌려주는 서버

  • MongoDB = 문서 저장 DB

    • mongo-express = DB를 웹에서 보는 관리자 UI

DB->HTML 까지 요청~응답 흐름

[브라우저] http://localhost:5173
   └─(fetch) GET /posts ─────────────────────────────────┐
[React(Vite dev서버)]                                    │
                                                         ▼
                                         http://localhost:8000 (포트 매핑)
                                           [FastAPI(Uvicorn)]
                                              │   └─ CORS 허용
                                              ▼
                                mongodb://mongo:27017 (컨테이너 네트워크)
                                       [MongoDB (posts 컬렉션)]
                                              │
                                         결과 문서들
                                              ▼
                                   [FastAPI] → JSON 변환(id 문자열화)
                                              ▼
                                 [브라우저(React)] 상태 업데이트 → HTML 렌더

환경 한눈에

docker 활용해서 로컬에 빌드해보았다

[브라우저] (호스트 OS)
   │
   ├─ http://localhost:5173  →  [frontend 컨테이너: Vite dev 서버]
   │                                 └ React 앱(HTML/JS/CSS) 서빙, HMR
   │
   ├─ http://localhost:8000  →  [backend 컨테이너: Uvicorn + FastAPI]
   │                                 └ Motor(비동기 드라이버)로 Mongo 접속
   │
   └─ http://localhost:8081  →  [mongo-express 컨테이너: DB UI]
                                 (관리자 화면)

[MongoDB 컨테이너: mongo]  ← backend가 내부 네트워크로 `mongodb://mongo:27017` 접속

도커로 각 서비스 리눅스 컨테이너로 띄우고, 포트/볼륨/환경 변수까지 표준화 한다

컨테이너는 같은 네트워크라 서비스명으로 통신하고 브라우저는 호스트 포트로 접근한다

순서

  1. 페이지 로드 & 목록 조회 (GET /posts)

  2. 글 작성 (POST /posts)


1-1 브라우저 -> Vite dev 서버

  • 역할: 개발용 정적 서버 + HMR1

  • 동작:

    1. 사용자가 접속

    2. Vite가 index.html, src/main.tsx, src/App.tsx, index/css 등을 ESM 모듈2로 서빙

    3. Tailwind는 JIT3 방식으로 사용한 클래스만 CSS 생성

1-2 React 앱 -> 백엔드 호출

  • 역할: UI 로직

  • 주요 코드:
      const API = import.meta.env.VITE_API_BASE ?? "http://localhost:8000";
      useEffect(() => { load(); }, []);
      async function load() {
      const res = await fetch(`${API}/posts`);   // ← 여기서 GET /posts
      setPosts(await res.json());
      }
    
  • 상호작용:

    • 브라우저가 HTTP GET /posts 요청을 localhost:8000으로 전송

    • CORS: 미들웨어4가 Access-Control-Allow-Origin5만 맞춰주면 된다고 한다

1-3 Uvicorn(ASGI 서버) → FastAPI(라우팅)

  • 역할:

    • Uvicorn: 소켓 수신 -> ASGI 프로토콜로 FastAPI에 전달

    • FastAPI: 라우팅(@app.get("/posts"))6 후 엔드포인트 함수 실행

  • 주요 코드:
      @app.get("/posts")
      async def list_posts(skip: int = 0, limit: int = 20):
          cursor = posts.find().skip(skip).limit(limit).sort("_id", -1)
          return [to_out(d) async for d in cursor]
    

    1-4 Motor(비동기 드라이버) → MongoDB

  • 역할: DB와 대화하는 라이브러리

  • 상호작용:

    • posts.find()가 비동기 커서7 반환 → async for 로 문서들을 끌어옴

    • 이동안 FastAPI는 await 덕분에 다른 요청도 처리 가능(동시성↑)

1-5 MongoDB → FastAPI → 브라우저

  • 직렬화:

    • Mongo 문서는 _id가 Objectid -> 그대로 JSON에 못 담음

    • 헬퍼 to_out()이 _id를 str()로 바꿔 id 필드에 넣음

  • 응답:

    • FastAPI가 JSON과 200 OK로 반환, 헤더 Content-Type: application/json
  • React:

    • setPosts()로 상태 업데이트 -> 가상 DOM8 비교 -> 실제 DOM9 렌더

    • Tailwind 클래스 적용된 HTML 표시




2-1 React 폼 전송

await fetch(`${API}/posts`, {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({ title, body })
});
  • CORS 사전요청:

    • Content-Type: application/json은 브라우저가 먼저 OPTIONS 요청을 보냄

    • FastAPI의 CORSMiddleware가 Access-Control-* 헤더를 응답 → 본 요청 허용

2-2 FastAPI: 라우팅 + Pydantic 검증

class PostIn(BaseModel):
    title: str = Field(min_length=1, max_length=100)
    body: str

@app.post("/posts", response_model=PostOut, status_code=201)
async def create_post(p: PostIn):   # ← JSON이 자동으로 PostIn으로 파싱/검증
    res = await posts.insert_one(p.dict())
    doc = await posts.find_one({"_id": res.inserted_id})
    return to_out(doc)
  • Pydantic 역할:

    • JSON → PostIn으로 파싱 & 유효성 검사

    • 규칙 위반 시 FastAPI가 422 응답과 에러 JSON 자동 반환(함수 본문 실행 안 됨)

  • 성공 시:

    • Motor로 insert_one → Mongo가 _id 생성

    • 다시 find_one으로 방금 문서 조회 → _id 문자열화 → 201 Created + JSON

2-3 React 후처리

  • 성공 후 load() 재호출 → 목록 갱신 → 새로운 글 화면 반영


요소들 역할 정리

  • Vite dev 서버: 개발 중 정적 파일/모듈 서빙 + HMR

  • React: UI 컴포넌트 + 상태관리

    • fetch로 API 호출
  • CORS 미들웨어: 다른 출처 호출 허용

    • Preflight/헤더 응답
  • Uvicorn(ASGI 서버): HTTP 소켓 수신, FastAPI 호출

  • FastAPI(라우팅): URL/메서드 매칭, 의존성/미들웨어, 응답 포맷

  • Pydantic(모델/검증): 요청/응답 스키마와 자동 유효성 검사

  • Motor(비동기 드라이버): Mongo 프로토콜로 비동기 I/O 수행

  • MongoDB: 문서 저장/조회/수정/삭제

    • _id:ObjectID
  • to_out 직렬화: _id -> 문자열 id로 변환해 JSON 호환




유의점은 비동기라서 await / async for로 논블로킹(기다리는 동안 다른 요청 처리) 하게 읽어온다

setState()가 호출되면 새 가상 DOM을 만들고 이전 것과 비교해서 바뀐 부분만 실제 DOM에 반영한다

  1. Hot Module Replacement, 코드 수정시 전부 고치는게 아닌 변경된 곳만 교체해서 실행 애플리케이션에 반영 ↩

  2. ECMAScript Module, 자바스크립트에서 공식적으로 표준화된 모듈 시스템 ↩

  3. Just-in-Time compile, 실행하기 전에 컴파일 하는게 아닌 프로그램 실행하며 필요한 부분 즉석으로 컴파일 하는 방식 ↩

  4. 미들웨어, 요청들어오고 라우트 핸들러 실행, 응답 나감 사이에 끼어있는 중간 처리자다 ↩

  5. CORS에 사용되는 HTTP 응답 헤더 중 하나로 어떤 도메인에서 요청을 허용할 것인지 명시한다 ↩

  6. “어떤 URL + HTTP 메서드 → 어떤 함수가 처리할지”를 매핑하는 것. 여기서는 이후 매핑된 실행 함수인 엔드포인터 함수(=핸들러) 까지 실행한다 ↩

  7. DB에서 문서 한 번에 다 못받을때 사용하는 네트워크 I/O 이터레이터(배열 참조시 사용하는 개체)
     ↩

  8. React가 메모리 안에서 갖고 있는 경량 복사본 트리다
     ↩

  9. 브라우저가 실제로 들고 있는 트리로 여기 직접 조작하면 렌더 비용이 크다 ↩