Загружаем каталог…
Загружаем каталог…
Node.js의 비동기 처리에 대해 공부한 뒤, 실제 클라이언트의 요청이 어떻게 서버까지 전달되는지 궁금해졌다. NestJS를 사용하면서 @Get() , @Post() , @Body() , @Param() 같은 기능은 사용해봤지만, 이것들이 HTTP에서 어떤 의미를 가지고 있는지 제대로 정리해본 적은 없었다. 이번에는 다음 내용을 중심으로 정리했다. Client와 Server Request와 Response HTTP Method HTTP Status Code Header와 Body Path Parameter와 Query Parameter IP와 Port Domain과 DNS HTTP와 HTTPS TCP 브라우저에 URL을 입력했을 때의 전체 흐름 1. Client와 Server 웹 통신의 가장 기본적인 구조는 Client와 Server다. 간단하게 생각하면 Client는 요청하는 쪽 , Server는 요청을 받아 처리하고 응답하는 쪽 이다. Client │ │ Request ▼ Server │ │ 처리 ▼ Database │ │ 결과 ▼ Server │ │ Response ▼ Client 예를 들어 React 애플리케이션에서 다음 요청을 보냈다고 생각해보자. axios.get("/api/posts"); 이 경우 요청을 보내는 React 애플리케이션은 Client 역할을 한다. 반대로 NestJS 서버는 요청을 받아 필요한 작업을 수행하고 결과를 반환한다. @Get('/posts') async getPosts() { return this.postService.findAll(); } 여기서 중요한 점은 Client가 반드시 브라우저일 필요는 없다는 것이다. 모바일 애플리케이션도 Client가 될 수 있고, 다른 Server가 특정 Server에게 요청을 보낸다면 그 순간에는 요청을 보내는 Server가 Client 역할을 할 수도 있다. 2. Request와 Response HTTP 통신에서는 Client가 Server에게 Request(요청) 를 보내고 Server는 처리 결과를 Response(응답) 로 반환한다. 예를 들어 10번 게시글을 조회한다고 해보자. Client │ │ GET /posts/10 │ Request ▼ Server 서버가 정상적으로 게시글을 찾았다면 다음과 같은 응답을 보낼 수 있다. Server │ │ 200 OK │ │ { │ "id": 10, │ "title": "Node.js 공부" │ } ▼ Client 즉 가장 기본적인 HTTP 통신 구조는 다음과 같다. Client ─── Request ───▶ Server Client ◀── Response ─── Server 3. HTTP Method HTTP 요청에는 해당 리소스에 어떤 작업을 하고 싶은지 나타내는 Method가 존재한다. 대표적으로 다음과 같은 Method를 사용한다. Method 일반적인 의미 예시 GET 조회 게시글 조회 POST 생성 게시글 작성 PUT 전체 교체/수정 게시글 전체 변경 PATCH 부분 수정 제목만 변경 DELETE 삭제 게시글 삭제 NestJS에서는 다음과 같이 사용한다. @Get('/posts') findAll() {} @Post('/posts') create() {} @Patch('/posts/:id') update() {} @Delete('/posts/:id') remove() {} URL이 같더라도 Method가 다르면 의미가 달라질 수 있다. GET /posts/10 → 10번 게시글 조회 PATCH /posts/10 → 10번 게시글 수정 DELETE /posts/10 → 10번 게시글 삭제 특히 PUT 과 PATCH 의 차이를 알아둘 필요가 있다. 일반적으로 PUT 은 리소스를 전체적으로 교체하는 의미로 사용하고, PATCH 는 리소스의 일부를 변경하는 의미로 사용한다. 예를 들어 10번 게시글의 제목만 변경한다면 다음과 같이 표현할 수 있다. PATCH /posts/10 { "title": "수정된 제목" } 4. HTTP Status Code Server는 데이터를 반환하면서 요청 처리 결과를 나타내는 HTTP Status Code 도 전달한다. 대표적인 Status Code는 다음과 같다. Status Code 의미 200 OK 요청 성공 201 Created 리소스 생성 성공 204 No Content 성공했지만 응답 Body 없음 400 Bad Request 잘못된 요청 401 Unauthorized 인증 정보가 없거나 유효하지 않음 403 Forbidden 인증은 되었지만 권한이 없음 404 Not Found 요청한 리소스를 찾을 수 없음 409 Conflict 현재 리소스 상태와 요청이 충돌 500 Internal Server Error 서버 내부 오류 크게 보면 다음처럼 구분할 수 있다. 2xx → 성공 4xx → Client 요청과 관련된 문제 5xx → Server 내부 문제 401과 403의 차이 공부하면서 특히 구분할 필요가 있다고 느낀 부분이다. 401 Unauthorized 쉽게 생각하면 "누구인지 확인할 수 없다." 이다. 예를 들어 로그인이 필요한 API인데 Access Token이 없거나 유효하지 않다면 401을 반환할 수 있다. 로그인하지 않음 ↓ 관리자 API 요청 ↓ 401 Unauthorized 403 Forbidden 403은 사용자가 누구인지는 확인했지만 해당 작업을 수행할 권한이 없는 경우 다. 일반 사용자 로그인 성공 ↓ 관리자 전용 API 요청 ↓ 403 Forbidden 따라서 간단하게 기억하면 다음과 같다. 401 → 인증(Authentication) 403 → 권한/인가(Authorization) 5. Header와 Body HTTP Request에는 Method와 URL뿐만 아니라 Header와 Body 같은 정보도 포함될 수 있다. 예를 들어: PATCH /posts/10 Headers Content-Type: application/json Authorization: Bearer <token> Body { "title": "수정된 제목" } Header Header에는 요청이나 응답에 대한 부가 정보 가 들어간다. 예를 들어: Content-Type: application/json 은 Body가 JSON 형식이라는 것을 나타낼 수 있다. JWT 기반 인증을 사용하는 경우에는 다음과 같은 Header를 자주 볼 수 있다. Authorization: Bearer <access-token> NestJS에서는 이후 Guard 같은 기능을 이용해 인증 정보를 검사하는 구조와 연결할 수 있다. Client │ │ Authorization: Bearer JWT ▼ NestJS │ ▼ Guard │ ├─ 인증 실패 → 401 │ └─ 인증 성공 → Controller Body Body에는 서버로 전달하려는 실제 데이터가 들어갈 수 있다. 예를 들어 회원가입이라면: POST /users Content-Type: application/json { "email": "test@test.com", "password": "1234" } email , password 같은 데이터가 Body에 들어간다. 단, Request Body가 항상 JSON인 것은 아니다. JSON은 웹 API에서 많이 사용하는 데이터 형식 중 하나다. 6. Path Parameter, Query Parameter, Body NestJS에서 자주 사용했던 다음 세 가지도 HTTP 요청과 연결된다. @Param() @Query() @Body() Path Parameter 특정 리소스를 지정할 때 많이 사용한다. GET /posts/10 여기서 10 이 Path Parameter다. @Get('/posts/:id') findOne(@Param('id') id: string) { return this.postService.findOne(id); } 쉽게 질문으로 생각하면: "누구를 대상으로 할 것인가?" 라고 볼 수 있다. /users/3 → 3번 사용자 /posts/10 → 10번 게시글 /products/25 → 25번 상품 Query Parameter 검색, 필터링, 정렬, 페이지네이션 등의 조건을 전달할 때 많이 사용한다. GET /posts?page=2&size=10 ? 뒤에 Query Parameter가 위치한다. @Get('/posts') findAll( @Query('page') page: string, @Query('size') size: string, ) { // ... } 다음과 같은 요청도 가능하다. GET /products?category=computer&sort=price 쉽게 생각하면: "어떤 조건으로 가져올 것인가?" 라고 볼 수 있다. Body 생성하거나 수정하려는 실제 데이터를 전달할 때 많이 사용한다. POST /products { "name": "키보드", "price": 50000 } NestJS에서는 다음과 같이 받을 수 있다. @Post('/products') create(@Body() body: CreateProductDto) { return this.productService.create(body); } 따라서 세 가지를 간단하게 정리하면: Path Parameter → 누구를? Query Parameter → 어떤 조건으로? Body → 어떤 데이터를? 7. IP Address 지금까지는 Client와 Server가 통신한다고만 생각했다. 하지만 인터넷에는 수많은 Server가 존재한다. Client가 특정 Server에게 데이터를 보내려면 "어느 컴퓨터로 데이터를 보내야 하는가?" 를 알아야 한다. 이때 사용하는 것이 IP Address 다. 쉽게 비유하면 IP는 집 주소 와 비슷하다. Client │ │ ▼ 203.0.113.10 Server IP 주소를 통해 네트워크상에서 통신하려는 대상 컴퓨터를 구분할 수 있다. 8. Port 하지만 하나의 Server에서는 여러 서비스가 동시에 실행될 수 있다. 예를 들어 한 Server에 다음 프로그램들이 존재한다고 생각해보자. Server NestJS MySQL Redis SSH IP만 가지고는 어떤 서비스와 통신하고 싶은지 구분할 수 없다. 그래서 Port 를 사용한다. IP를 집 주소라고 생각한다면 Port는 문 번호 라고 생각할 수 있다. 203.0.113.10 ├── :3000 → NestJS ├── :3306 → MySQL └── :6379 → Redis NestJS에서 다음 코드를 사용한 것도 같은 의미다. await app.listen(3000); 즉 NestJS 애플리케이션이 3000번 Port에서 요청을 받을 수 있도록 실행하는 것이다. 따라서: IP → 어느 컴퓨터인가? Port → 해당 컴퓨터의 어느 서비스인가? 라고 이해할 수 있다. 9. localhost 개발하면서 자주 사용했던 주소가 있다. http://localhost:3000 localhost 는 현재 자기 자신의 컴퓨터를 가리키는 Host Name 이다. IPv4에서는 대표적으로 다음 루프백 주소가 사용된다. 127.0.0.1 따라서: localhost:3000 은 쉽게 말하면 "내 컴퓨터의 3000번 Port에서 실행 중인 서비스" 를 의미한다고 볼 수 있다. 10. Domain과 DNS 실제로 웹사이트를 사용할 때 IP 주소를 직접 외워서 입력하지는 않는다. 대신 다음과 같은 주소를 사용한다. example.com google.com naver.com 이처럼 사람이 기억하기 쉽게 만든 이름이 Domain 이다. 하지만 실제 네트워크 통신을 위해서는 대상 Server의 IP 주소가 필요하다. 여기서 DNS(Domain Name System) 가 등장한다. DNS는 간단하게 Domain Name에 대응되는 IP 주소를 찾아주는 시스템 이라고 이해할 수 있다. example.com │ ▼ DNS │ ▼ 203.0.113.10 전화번호부에 비유하면 이해하기 쉽다. 사람 이름 → 전화번호 Domain → IP Address 11. DNS 실패와 404는 다르다 처음에는 DNS가 IP를 찾지 못하면 404 Not Found 가 발생한다고 생각했다. 하지만 둘은 완전히 다른 단계의 문제다. 404 Not Found 404는 서버까지 HTTP Request가 정상적으로 도착했지만 서버가 요청한 리소스를 찾지 못한 경우 다. Client ↓ DNS 성공 ↓ Server까지 요청 도착 ↓ GET /posts/999 ↓ 999번 게시글 없음 ↓ 404 Not Found 반면 DNS가 실패한다면: Domain ↓ DNS ↓ IP를 찾을 수 없음 X Server까지 도달하지 못함 즉 HTTP 요청을 처리할 서버의 위치 자체를 찾지 못한 것이다. 따라서 이 경우 Server가 보내는 HTTP 404 와는 다르다. 간단하게 기억하면: DNS 실패 → 서버 위치 자체를 찾지 못함 404 → 서버까지 도착했지만 요청한 리소스를 찾지 못함 12. HTTP와 HTTPS HTTP는 Client와 Server가 어떤 형식으로 요청하고 응답할지 정의한 통신 프로토콜 이다. 지금까지 배운 다음 내용들이 HTTP와 관련되어 있다. Method URL Header Body Status Code HTTP의 기본 Port는 80 이다. HTTP → Port 80 하지만 HTTP 자체만으로는 통신 내용을 안전하게 보호하기 어렵다. 예를 들어 로그인 요청을 생각해보자. { "email": "test@test.com", "password": "1234" } 네트워크를 통해 민감한 정보를 전달한다면 통신 내용을 보호할 필요가 있다. 그래서 HTTPS를 사용한다. HTTPS는 HTTP 통신을 TLS를 이용해 보호하는 방식 으로 이해할 수 있다. HTTP + TLS ↓ HTTPS HTTPS의 기본 Port는 443 이다. HTTP → 80 HTTPS → 443 13. HTTPS가 제공하는 것 HTTPS/TLS의 중요한 목적을 크게 세 가지로 정리할 수 있다. 기밀성 Confidentiality 통신 내용을 암호화하여 제3자가 내용을 쉽게 읽지 못하도록 보호한다. 무결성 Integrity 통신 과정에서 데이터가 변조되었는지 확인할 수 있도록 한다. 인증 Authentication 서버가 제공하는 인증서 등을 검증하여 Client가 접속하려는 Server의 신원을 확인하는 데 사용한다. 따라서 단순히 "HTTPS는 HTTP보다 보안이 좋다." 라고만 기억하기보다는 기밀성 무결성 인증 이라는 세 가지 키워드를 같이 기억하는 것이 좋다. 14. TCP는 무엇일까? HTTP가 요청과 응답의 형식을 정의한다면, 실제 데이터를 상대방에게 신뢰성 있게 전달하는 과정 도 필요하다. 여기서 TCP가 등장한다. 현재 단계에서는 TCP를 데이터를 상대방에게 신뢰성 있게 전달하기 위한 프로토콜 이라고 이해했다. TCP는 데이터의 순서와 손실 등을 관리하고 필요한 경우 재전송하는 방식으로 신뢰성 있는 데이터 전달을 제공한다. 따라서 HTTP와 TCP는 역할이 다르다. HTTP → 무엇을 어떤 형식으로 요청하고 응답할 것인가? TCP → 데이터를 상대방에게 신뢰성 있게 어떻게 전달할 것인가? IP → 데이터를 어느 컴퓨터로 보낼 것인가? 15. TCP 3-Way Handshake TCP에서는 데이터를 본격적으로 주고받기 전에 연결을 설정하는 과정이 있다. 대표적인 것이 3-Way Handshake 다. Client Server ───── SYN ───────────────▶ "연결할래?" ◀──── SYN + ACK ────────── "응, 나도 준비됐어" ───── ACK ───────────────▶ "확인했어" 연결 성립 순서는 다음과 같다. SYN ↓ SYN + ACK ↓ ACK 처음에는 마지막 단계도 SYN 이라고 생각했지만, 마지막은 ACK 다. 현재 단계에서는 내부 구조를 깊게 들어가기보다는 TCP는 통신 전에 3-Way Handshake를 통해 연결을 설정한다. 정도로 이해했다. 16. HTTP와 TCP를 혼동하지 않기 공부하면서 HTTP와 TCP의 역할이 조금 섞이기도 했다. 처음에는 HTTP가 IP 주소와 Port를 가지고 직접 서버와 연결해주는 것이라고 생각했다. 하지만 역할을 구분해서 보면 다음과 같다. HTTP → 요청/응답의 형식과 의미 TCP → 신뢰성 있는 데이터 전달 IP → 목적지 컴퓨터 Port → 목적지 컴퓨터에서 통신할 서비스 예를 들어: GET /posts/10 Authorization: Bearer <token> 같은 요청의 의미와 형식은 HTTP와 관련된다. 반면 해당 데이터를 네트워크를 통해 신뢰성 있게 전달하는 것은 TCP가 담당하는 영역이다. 각 계층의 역할을 구분해서 생각하는 것이 중요했다. 17. 브라우저에 URL을 입력하면 어떻게 될까? 마지막으로 지금까지 공부한 내용을 하나의 흐름으로 연결해봤다. 브라우저에 다음 주소를 입력했다고 생각해보자. https://example.com/posts/10 1단계: Domain 확인 example.com 이라는 Domain을 확인한다. 하지만 실제 통신을 위해서는 Server의 IP 주소가 필요하다. 2단계: DNS 조회 DNS를 이용하여 Domain에 대응되는 IP 주소를 찾는다. example.com ↓ DNS ↓ 203.0.113.10 3단계: 목적지 확인 HTTPS를 사용하고 있으므로 별도의 Port가 지정되지 않았다면 기본적으로 443 Port를 사용한다. 개념적으로 목적지를 다음과 같이 생각할 수 있다. 203.0.113.10:443 4단계: TCP 연결 Server와 데이터를 주고받기 위해 TCP 연결을 설정한다. SYN ↓ SYN + ACK ↓ ACK 3-Way Handshake가 완료되면 TCP 연결이 성립한다. 5단계: TLS HTTPS이므로 TLS를 이용해 보호된 통신을 위한 절차를 진행한다. 이 과정에서 인증서를 통한 Server 신원 확인과 이후 통신을 보호하기 위한 과정 등이 이루어진다. 6단계: HTTP Request 이제 Client가 HTTP Request를 보낼 수 있다. GET /posts/10 필요한 경우 Header도 포함된다. Authorization: Bearer <access-token> 7단계: Server 처리 NestJS 서버라면 요청이 Controller로 전달될 수 있다. @Get('/posts/:id') async findOne(@Param('id') id: string) { return this.postService.findOne(id); } 그리고 Service 등을 통해 필요한 비즈니스 로직을 수행한다. DB와 관련된 내용은 다음 학습에서 이어서 공부할 예정이다. 8단계: HTTP Response Server가 요청을 처리하면 Client에게 Response를 반환한다. 성공했다면: 200 OK { "id": 10, "title": "Node.js 공부" } 요청한 게시글이 없다면: 404 Not Found 인증이 필요한데 인증 정보가 없다면: 401 Unauthorized 등의 응답을 받을 수 있다. 전체 흐름 정리 지금까지 배운 내용을 하나로 연결하면 다음과 같다. https://example.com/posts/10 │ ▼ Domain │ ▼ DNS Domain → IP │ ▼ IP + Port Port 443 │ ▼ TCP 3-Way Handshake │ ▼ TLS 암호화 / 무결성 / 인증 │ ▼ HTTP Request GET /posts/10 │ ▼ Server │ ▼ Controller / Service │ ▼ 필요한 작업 처리 │ ▼ HTTP Response 200 / 404 등 │ ▼ Client 각각의 역할을 한 줄로 정리하면: Domain → 사람이 기억하기 쉬운 서버 이름 DNS → Domain에 대응되는 IP 주소를 찾음 IP → 어느 컴퓨터로 데이터를 보낼 것인지 Port → 해당 컴퓨터의 어느 서비스와 통신할 것인지 TCP → 데이터를 신뢰성 있게 전달 TLS → 통신을 암호화하고 보호 HTTP → Client와 Server가 요청하고 응답하는 방식 공부하면서 헷갈렸던 부분 이번에 공부하면서 특히 세 가지를 잘못 이해하고 있었다. 1. DNS를 실패하면 404가 발생한다? 아니다. DNS 실패는 Server의 IP 주소를 찾지 못해 Server까지 요청이 도달하지 못한 것이다. 404는 Server까지 요청이 정상적으로 도착했지만 요청한 리소스를 찾지 못한 경우
То, что RADAR обнаружил и классифицировал для этой возможности. Это опубликованный источником текст, а не подтверждение, что предложение ещё действует.
백엔드 개발자가 알아야 할 HTTP와 네트워크 기초. Node.js의 비동기 처리에 대해 공부한 뒤, 실제 클라이언트의 요청이 어떻게 서버까지 전달되는지 궁금해졌다. NestJS를 사용하면서 @Get() , @Post() , @Body() , @Param() 같은 기능은 사용해봤지만, 이것들이 HTTP에서 어떤 의미를 가지고 있는지 제대로 정리해본 적은 없었다. 이번에는 다음 내용을 중심으로 정리했다. Client와 Server Request와 Response HTTP Method HTTP Status Code Header와 Body Path Parameter와 Query Parameter IP와 Port Domain과 DNS HTTP와 HTTPS TCP 브라우저에 URL을 입력했을 때의 전체 흐름 1.…
Открыть источник