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: 미들웨어4Access-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()_idstr()로 바꿔 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의 CORSMiddlewareAccess-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. 브라우저가 실제로 들고 있는 트리로 여기 직접 조작하면 렌더 비용이 크다