240926 TIL - 입문/숙련 복습주차 1

LIHA·2024년 9월 26일
0

내일배움캠프

목록 보기
62/108
post-thumbnail
post-custom-banner

뼈대잡기

오늘의 할일

  • 승현튜터님 해설강의 보고 DB 분리하는 것 다시 보기
  • 입문숙련 강의 복습하고 아이템 시뮬레이터 이전 코드 이해하기
  • 내일 챌린지반 숙제 - SQL 4문제?

입문숙련 복습

라우팅은 뭔가요? 요청 조건에 대응해 '응답하는 방식'

OSI 7계층 중 3층인 네트워크 계층에도 라우터가 있다. 패킷이 목적지까지 가도록 도와주는 녀석인데, 라우터도 비슷하다. 요청을 받으면 이걸 처리할 수 있는 함수가 있는 URL을 가진 애한테 이 리퀘스트를 보내준다.

그래서 라우터가 무엇? 요청 처리를 도와주는 Express.js의 '기능'

기본적으로 다음의 형태를 가진다고 한다.
router.METHOD(PATH, HANDLER)

이 형태를 보고 아이템 시뮬레이터나 풋살 프로젝트 때 튜터님들이 말씀하신 '핸들러'가 뭔지 이해했다. 핸들러는 '라우트가 일치할 때 실행되는 함수' 라고 한다.

app.use('/api', [라우터 뭉태기])는요

/api로 요청이 들어오면 저 라우터 뭉태기를 조회해달라는 얘기. /api 주소로 들어온 요청을 저 라우터 뭉태기에 전달하게 된다.
-> 얘는 일종의 전역 미들웨어인데, 서버로 들어오는 모든 요청에 대해 공통적인 처리를 하고 싶을 때 쓴다고.

Auth 헤더로 JWT를 전달한다는 게 이 얘기구나!

req에는 URL, HTTP Method, 헤더, 쿼리파라미터, 바디 데이터 등이 포함되고,
res에는 상태 코드, 응답 데이터, 응답 헤더 등이 포함된다.

-> 아이템 시뮬레이터에서 - **클라이언트에서는** 쿠키로 JWT를 전달하지 않습니다.**오로지 Authorization 헤더로만 JWT를 전달**하니 이 점 유의해주세요! 라고 써있던 것이 이런 말이었구나. req.headers에 JWT를 담아 보내주고는 있었지만 그냥 쿠키 쓰지 말라길래 그런가보다 했는데, req와 res 모두 헤더가 있고 거기에 담아달라는 말이었다.
-> 헷갈림 주의 - JWT가 헤더, 페이로드, 시그니처로 3등분 되는 구조이긴 한데, 여기서 말하는 헤더는 JWT의 헤더가 아니고 익스프레스의 req 혹은 res의 헤더를 말한다.

Express는 Node의 서버 모듈 중 하나

Node.js은 JS 실행기, Express는 그런 Node의 서버 모듈 중 하나. 대표적으로 HTTP 모듈과 Express가 있는데, Express가 HTTP 모듈을 확장해서 만든 것이기 때문에 HTTP의 명령어도 상속받은 느낌으로 쓸 수 있다.

제대로 공부하지 않고 넘어갔던 Express의 req, res 객체들

req

  • req.app - req 객체를 통해 익스프레스의 app 객체에 접근
  • req.ip - 요청한 클라이언트의 주소가 담겨있음. 로깅 시스템 같은 것에 사용할 수 있다.
  • req.body - express.json() 미들웨어를 이용해야 이 객체를 사용할 수 있다. 바디 파서 라고도 한다. key-value 데이터 형식으로 JSON 형태를 띄고 있다. URL에 포함되지 않아 민감정보 같은 걸 담을 수 있다.
  • req.query - URL중 ?로 표시되는 쿼리 스트링으로 전달된 정보가 담긴 객체. URL에 원하는 key-value를 삽입하여 데이터를 전달한다.
    -> 특정 콘텐츠의 위치를 표시하거나 웹 페이지에 특정한 옵션을 설정할 때 사용. (게시글 정렬, 특정 날짜 게시글 조회 등)
    -> 서버 리소스를 필터링하거나 정렬하는 데 사용한다. GET Method에서 많이 사용한다.
    ex)sparta.com/posts?sort=desc&page=3&limit=10
    -> 내림차순 정렬, 3페이지 조회, 게시글 10개까지만
  • req.cookie - cookie-parser 미들웨어를 이용해야 이 객체를 사용할 수 있다. 쿠키 정보를 담을 때 사용한다.
  • req.get(Header) - 헤더에 저장된 값을 가져오고 싶을 때 사용.

res

  • res.app - res 객체를 통해 익스프레스의 app 객체에 접근.
  • res.send(데이터) - 다양한 유형의 데이터를 포함하여 response 전달. 헤더의 컨텐츠 타입이 데이터 유형에 따라 다름.
    (컨텐츠 타입은 서버가 클라에게 전달하는 데이터 타입을 지정할 때 사용됨)
    ex) res.send('Hello, World!')
  • res.json(JSON) - JSON 형식으로 response를 전달. 헤더의 컨텐츠 타입이 application/json으로 고정.
  • res.end() - 데이터 없이 response를 전달하고 통신을 끝냄.
  • res.redirect(주소) 리다이렉트할 주소와 함께 response를 전달.

TMI) res에 status를 명시하지 않으면 200이 자동적으로 전달된다고 한다.

req, res는 알겠는데 next는 뭐에요?

next가 붙어있다면 이건 미들웨어다. 다음 스택으로 정의된 미들웨어로 넘겨주는 역할. 이 next가 미들웨어의 핵심 기능.

위와 같은 이미지가 있다. res.send()를 하면 다음 미들웨어를 처리하지 않고 바로 response를 날리고 끝나 버리지만, next()를 하게 되면 다음 미들웨어로 뿅 뛰어 그녀석을 실행하게 된다.
-> 미들웨어를 거치면서 next가 실행되지 않으면 다음 미들웨어는 실행되지 않고 클라이언트의 요청은 거기서 종료된다.
-> 그런데 res도 없으면 다음 미들웨어를 실행도 안 하는데 보내주고 끝낼 응답값도 없으니 거기서 무한정 대기하는 상태가 되어 버린다.
-> 그러니 next를 쓰거나 return으로 응답을 돌려주고 끝내도록 하자.
-> res.send()나 res.json() 등의 메서드를 호출하는 경우에는 next()를 호출하면 안 된다! 이러면 이미 요청이 종료된 상태에서 다른 미들웨어가 응답을 보내려고 해서 중복된 요청이 전달되는 문제가 발생하게 된다.

그래서 라우터와 미들웨어는 뭐가 다른가요?

미들웨어는 서버의 요청-응답 과정에서 중간에 위치하여 특정 기능을 수행하는 '함수' 라고 볼 수 있다.

라우터와 미들웨어는 서로 다른 방식처럼 보이지만 라우터는 미들웨어 기반으로 구현된 '객체'이므로 미들웨어와 동일한 방식으로 작동한다.

-> 즉, 라우터는 미들웨어 함수를 특정 경로에 바인딩하는 역할을 하며, 요청이 들어온 URL 경로에 따라 서로 다른 미들웨어를 실행시킬 수 있게 도와준다.
-> app.use("/api", [router, todosRouter]); 이렇게 생긴 코드를 보면, 일단 app.use를 통해 전역 미들웨어에 등록한 것이고, /api라는 경로로 요청이 들어왔을 때 오른쪽에 있는 라우터들에게 요청을 할당해서 처리할 수 있는 핸들러가 있는지 순차적으로 조회하는 것.

미들웨어의 구분은 대강 요렇다

  • app.use(Middleware) : 모든 요청에서 미들웨어가 실행된다.
  • app.use(’/api’, Middleware) : /api로 시작하는 모든 요청에서 미들웨어를 실행한다.
  • app.post(’/api’, Middleware, (req,res,)=>{} ) : /api로 시작하는 POST 요청에서 미들웨어를 실행한다.

마지막에 있는 건 라우터에서 보던 형식과 비슷한데?
-> 이걸 app.js 파일 내에 모두 써줄 수 없으니 라우터로 분리하여 모듈화 하는 것

prisma에서 1:1 관계를 맺을 땐 해당 Id에 @unique를 넣어야 한다

예를 들어 Users 테이블과 UserInfos 테이블이 있다면 이 둘은 무조건 1:1의 연관관계가 있어야 한다. 그때 프리즈마 스키마는 아래와 같다.

Users 테이블은 userInfos가 없을 수도 있으니 ?로 걸리지만(추후 작성할 수도 있으니까)

UserInfos는 Users 없이는 존재할 수 없고, 1:1 관계로 걸리기 때문에 userId에 @unique가 붙었다.

관계 너무 어렵게 생각하지 말기

보통 일반적으로는 어느 한쪽은 1이라고 생각하고 릴레이션을 맺자
(다만 배민 주문 맵핑처럼 되는 경우는 예외 -> 얘도 주문테이블을 만들어서 1유저 1메뉴 주문으로 만들 수 있다)

댓글은 게시글의 하위로써 존재하니까...?!

METHOD는 POST이고, URL이 /api/posts/:postId/comments 라는 식으로 나올 것이다. 작성 시에는 인증 미들웨어를 통해서 로그인된 사용자가 맞는지 인증할 것이다. 조회 시에는 특별히 인증이 필요없고 GET으로 불러올 수 있을 것이다.
-> 이것을 보며
1. 우와 이런 API도 있었나? 나 왜 URL부터 처음 보는 것 같지!?
2. 장착 아이템 로직을 이렇게 작성할 수 있지 않을까?
라는 생각이 들었다. 🤔 나 새삼 기억하지 못하는 게 되게 많구나. 강의를 대체 어떻게 들었던거지...


아이템 시뮬레이터 보완

튜터님이 쓰신 명령어의 의미?

npx prisma db push --schema=./schema.prisma
이 블로그를 참고하니 '스키마 폴더명은 반드시 schema일 필요는 없지만, schema.prisma 파일은 해당 폴더 하위에 반드시 존재해야 한다' 고 써 있었다.
아마 --schema로 시작하는 구문은 내가 푸쉬할 스키마는 이 폴더에 있는 schema.prisma 파일이라는 뜻인 듯 하다.
-> 아마 모든걸 다 푸쉬하는게 아니라 이 폴더의 스키마 파일만 푸쉬해달라는 얘기인 것 같다😏


게임서버 심화

게임회사는 보통 3권분립 3원 체제로 이루어져 있다

프로젝트, 개발, 아트의 장인 PD, TD, AD가 머리를 맞대어 나오는 것이 보통 프로젝트의 방향. PD가 시나리오를 쓴다던지 한다.

참된 개발자라면 라꾸라꾸 침대를 사가자

서버팀이 바쁜 것은 주로 라이브 오픈 전후. 그때는 사실 모든 팀이 각오를 해둬야 하지만 그 외에는 생각만큼 바쁘지 않다고.

사실 HTTP는 에이스가 아니었습니다

철수가 작년에 샀던 과자를 또 사고싶어 '전에 그걸로' 라고 요청을 해도 사이트는 알아듣지 못한다. HTTP는 Stateless이기 때문.

철수: 전에 그걸로. 3개.
사이트: 롸? 누구세요?

그래서 세번 결혼하는 여자 세번 악수하는 남자인 연결지향성 TCP가 이 전쟁을 끝내러 두둥등장 한다.

TCP의 양방향 통신 핑퐁핑퐁

아니 그래서 TCP가 대체 뭔데요 이 오덕아! 하시는 분들은 참고 블로그 로.

TCP는 연결 시작 및 종료 전후로 총 3번의 확인 핑퐁단계를 거친다. 위는 연결 시작때의 이미지.

  1. 나 연결해도 돼?
  2. 어어 돼! 연결했어! 나도 연결해도 돼?
  3. 어어 나도 괜찮아! OK 연결했다!

대강 이렇게 되는 것이다. 일단 NO HELLO RULE 이라서 좋다 강의에서 알려주신 양방향 통신(Full-duplex) 순서는 다음과 같다.

  1. 서버가 접속요청을 받기위한 소켓을 포트마냥 활짝 열면 (Listen)
  2. 클라이언트는 소켓을 만들고 서버에 접속 요청을 한다 (Connect)
  3. 서버는 접속요청을 받아 클라이언트와 통신할 소켓을 따로 만든다 (Accept)
  4. 소켓을 통해 서로 데이터를 주고 받는다 (Send&Receive의 반복)
  5. 통신을 마치면 소켓을 닫는다 (Close -> 상대방은 Receive로 인지 가능)

그러면 HTTP로 Stateful한 연결은 안돼요? 네 안돼요

그게 되면 웹소켓이라는게 나오지 않았을 것이다. HTTP는 '연결이 끊긴다'는 개념 자체가 없는게, '애초에 연결이라는게 지속되지 않는 프로토콜' 이기 때문이다. 던진다. 받는다. 끝.
-> 그렇기 때문에 HTTP는 기본적으로 Stateless이고 비연결성 이라는 성질을 띠는 것!
(택배 기사님은 당신의 집 문앞에 택배를 던져두고 가버리지 당신이 받을때까지 기다리거나 벨을 누르지 않는다.)

웹소켓은 HTTP보다 머리가 작아요

웹소켓의 장점은 HTTP보다 헤더에 포함되는 정보가 정말 작다. 제너럴 헤더니 리퀘스트 헤더니 나처럼 묵직한 머리를 가진 HTTP와는 달리 웹소켓의 헤더는 16진수 딱 두개만이 들어있기 때문. 야호! 라고 하긴 이른게 그 16진수 안에도 굉장히 많은 정보들이 들어있긴 하다.

profile
갑자기 왜 춤춰?
post-custom-banner

0개의 댓글