diff --git a/week07/keyword/keyword.md b/week07/keyword/keyword.md new file mode 100644 index 0000000..d88de6c --- /dev/null +++ b/week07/keyword/keyword.md @@ -0,0 +1,240 @@ +- 미들웨어 + + **✅정의:** + + 미들웨어는 **클라이언트의 요청(Request)이 서버에 도착했을 때**, + + **요청을 가공하거나 검사하거나, 응답을 변경하거나**, + + **다음 작업으로 넘겨주는 중간 처리자** + + --- + + **🛠️ Express.js에서 쓰는 예시:** + + ``` + const express = require('express'); + const app = express(); + + // JSON 데이터를 읽을 수 있게 해주는 미들웨어 + app.use(express.json()); + + // 직접 만든 미들웨어 + app.use((req, res, next) => { + console.log('요청 들어옴:', req.method, req.url); + next(); // 다음 미들웨어나 라우터로 이동 + }); + + ``` + + --- + + **💎 속성 (특징):** + + | **속성** | **설명** | + | --- | --- | + | **요청/응답 중간 처리** | 요청을 받아서 데이터를 바꾸거나 검사할 수 있음 | + | **순차적으로 실행됨** | 여러 개 미들웨어가 있을 때 위에서 아래로 순서대로 실행 | + | **`next()` 함수 사용** | 다음 미들웨어로 넘기려면 `next()` 를 반드시 호출해야함 | + | **종류가 다양함** | 인증, 로깅, 에러 처리, 응답 포맷 설정 등 다양함 | + + --- + + **👍 장점** + + | **장점** | **설명** | + | --- | --- | + | **로직 분리 가능** | 인증, 로깅, 에러 처리 등 역할을 분리할 수 있어 코드가 깔끔해짐 | + | **재사용 가능** | 공통된 처리를 모든 라우터에 적용할 수 있음 | + | **순서 조절 가능** | 미들웨어 순서를 바꿔서 동작 순서를 쉽게 조절할 수 있음 | + + --- + + **👎 단점** + + | **단점** | **설명** | + | --- | --- | + | **순서 실수하면 오류** | `next()` 호출 순서 잘못되면 라우터가 실행 안 되거나 무한 루프가 날 수 있음 | + | **비직관적인 흐름** | 처음 보면 어디서 뭘 하는지 코드가 헷갈릴 수 있음 | +- HTTP 상태 코드 + + **✅ 정의:** + + HTTP 상태 코드는 **클라이언트가 서버에 요청을 보냈을 때**, + + 서버가 **요청을 잘 받았는지, 문제가 있는지**를 숫자로 알려주는 신호 + + --- + + **💡 속성 (특징):** + + | **속성** | **설명** | + | --- | --- | + | **3자리 숫자** | 항상 세 자리로 되어 있음 (`200`, `404`, `500` 등) | + | **앞자리로 종류 구분** | 1xx~5xx로 나눠져 있어 각각 다른 의미 | + | **HTTP 응답의 핵심** | 서버가 어떤 상태인지 가장 먼저 알려주는 정보 | + | **표준 규격** | 전 세계 모든 브라우저/서버가 이 규칙을 따름 | + + --- + + **📊 종류별 코드와 의미** + + | **분류** | **상태 코드** | **의미** | **예시** | + | --- | --- | --- | --- | + | **1xx** (정보) | `100`, `101` | 요청을 받고 처리 중 | 거의 안 씀 | + | **2xx** (성공) | `200`, `201` | 요청 성공 | 조회, 생성 성공 등 | + | **3xx** (리다이렉트) | `301`, `302` | 다른 주소로 이동해 | 로그인 후 리디렉션 | + | **4xx** (클라이언트 오류) | `400`, `401`, `403`, `404` | 요청이 잘못됐어 | 유효하지 않은 요청, 없는 주소 등 | + | **5xx** (서버 오류) | `500`, `502`, `503` | 서버 문제야 | 서버 코드 오류, 다운 등 | + + --- + + **🛠️ Express.js에서 상태 코드 쓰는 예시** + + ``` + res.status(200).json({ success: true, message: '성공!' }); + res.status(404).json({ success: false, message: '찾을 수 없습니다' }); + res.status(500).json({ success: false, message: '서버 오류입니다' }); + + ``` + + --- + + **👍 장점** + + | **장점** | **설명** | + | --- | --- | + | **빠른 오류 인식** | 숫자만 보고도 어떤 오류인지 바로 파악 가능 | + | **표준화된 규칙** | 전 세계 개발자들이 모두 같은 의미로 사용 | + | **프론트/백 간 통신 최적화** | 에러가 있으면 프론트가 즉시 처리 가능 | + | **로깅 및 디버깅에 유용** | 로그에 남기면 문제 추적이 쉬움 | + + --- + + **👎 단점** + + | **단점** | **설명** | + | --- | --- | + | **숫자만 보면 직관적이지 않음** | 처음엔 `422`, `403`, `409` 등 숫자만 봐선 무슨 뜻인지 모름 | + | **모호한 코드도 있음** | 같은 상황에 `400`, `422`, `409` 중 어떤 걸 써야 할지 헷갈릴 수 있음 | + | **프론트가 잘못 해석할 수도 있음** | 상태 코드만 보고 프론트가 잘못된 처리할 수 있음 | +- 에러 핸들링(Error Handling) + + **✅ 정의:** + + 에러 핸들링은 **코드 실행 중에 문제가 발생했을 때** + + 프로그램이 **바로 죽지 않도록 잡아서 처리하고**, + + **사용자에게는 적절한 응답을 보내고**, + + **개발자는 디버깅할 수 있도록 기록을 남기는 과정** + + --- + + **💡 속성 (특징):** + + | **속성** | **설명** | + | --- | --- | + | **예외 상황 처리** | DB 오류, 유효성 검사 실패, 네트워크 오류 등 예상/비예상 에러를 처리 | + | **흐름 제어** | 에러가 나도 서버 전체가 멈추지 않고, 정해진 방식대로 응답을 보냄 | + | **로그와 연계** | 에러 내용을 파일/콘솔/모니터링 툴에 남겨서 추후 분석 가능 | + | **사용자 친화적 응답** | 내부 상세 에러는 숨기고, 사용자에게는 이해 가능한 메시지만 전달 | + | **일관성 유지** | 모든 API에서 에러 형식, 상태 코드, 응답 구조를 통일할 수 있음 | + + --- + + **🧱 에러 핸들링 구성 요소 정리** + + | **구성 요소** | **역할** | + | --- | --- | + | **예외 발생 지점** | DB 조회, 외부 API 호출, 비즈니스 로직, 유효성 검사 등에서 에러가 발생 | + | **에러 전달 (`throw`, `next(err)`)** | 발생한 에러를 전역 에러 핸들러로 넘기는 과정 | + | **전역 에러 미들웨어** | 모든 라우터/미들웨어에서 발생한 에러를 한 곳에서 모아서 처리 | + | **로그 기록** | `console.error` 또는 Winston, Morgan 같은 로깅 라이브러리로 저장 | + | **사용자 응답 생성** | HTTP 상태 코드 + 에러 메시지 + 필요 시 에러 코드(JSON 필드) 등을 만들어 응답- | + + --- + + **🛠️ Express.js에서 쓰는 기본 패턴 예시** + + 1. **라우터에서 에러 던지기 (`throw`, `next(err)`)** + + ```jsx + app.get('/user/:id', async (req, res, next) => { + try { + const user = await findUserById(req.params.id); + if (!user) { + // 커스텀 에러 던지기 + const error = new Error('사용자를 찾을 수 없습니다.'); + error.status = 404; + throw error; + } + res.json({ success: true, data: user }); + } catch (err) { + next(err); // 에러 핸들러 미들웨어로 전달 + } + }); + + ``` + + 2. **전역 에러 핸들러 미들웨어** + + ```jsx + // 마지막에 두는 게 중요! + app.use((err, req, res, next) => { + console.error('에러 발생:', err.message); + + const status = err.status || 500; + const message = + status === 500 + ? '서버 내부 오류가 발생했습니다.' + : err.message; + + res.status(status).json({ + success: false, + message, + }); + }); + + ``` + + 3. **커스텀 에러 클래스 만들어 쓰기 (선택)** + + ```jsx + class HttpError extends Error { + constructor(status, message) { + super(message); + this.status = status; + } + } + + // 사용 예시 + app.get('/example', (req, res, next) => { + return next(new HttpError(400, '잘못된 요청입니다.')); + }); + - + ``` + + --- + + **👍 장점** + + | **장점** | **설명** | + | --- | --- | + | **서버 안정성 향상** | 에러가 나도 서버 전체가 죽지 않고, 예측 가능한 방식으로 동작 | + | **디버깅 쉬움** | 에러 로그가 쌓이기 때문에, 나중에 어떤 문제가 있었는지 추적 가능 | + | **일관된 응답 형식** | 모든 API에서 `{ success, message, data }` 같은 통일된 포맷 사용 가능 | + | **프론트와 협업에 좋음** | 상황별 에러 코드/메시지를 정해두면, 프론트가 처리 로직을 깔끔하게 작성 | + | **보안성 향상** | 내부 에러 내용을 그대로 노출하지 않고, 안전한 메시지로 가공 가능 | + + --- + + **👎 단점** + + | **단점** | **설명** | + | --- | --- | + | **설계가 필요함** | “어떤 상황에 어떤 코드/메시지를 쓸지” 미리 규칙을 정해줘야 함 | + | **중복 처리 위험** | 라우터마다 따로 `try/catch` 쓰면 코드가 지저분해질 수 있음 | + | **흐름 파악이 어려울 수 있음** | `next(err)`로 여기저기서 던지다 보면 처음 보는 사람은 흐름이 헷갈림 | + | **관리 안 하면 카오스** | 상태 코드, 에러 메시지, 에러 구조를 제각각 쓰면 나중에 정리 지옥 됨 | \ No newline at end of file diff --git a/week07/mission/mission.md b/week07/mission/mission.md new file mode 100644 index 0000000..e69de29