LabHub
배우기 러닝패스 코스

Node.jsバックエンド — フレームワークが隠したもの

Nodeの標準ライブラリでAPIを立てる

LabHub 에서 이어서 보기

한국어 원문으로 표시합니다.

목표

Nest 없이 Node 표준 라이브러리만으로 작은 주문 API 를 세웁니다. 라우팅 표, 입력 검증, 출력 모양, 의존성 주입, 이벤트 루프까지 여덟 단계입니다.

왜 이렇게 하는가

실습 파드는 DNS 만 열려 있어 npm install 이 안 됩니다. 그런데 그 제약이 오히려 이 코스에 맞습니다 — 프레임워크가 대신해 주던 판단을 직접 내려 보면, 나중에 Nest 를 읽을 때 각 장치가 무엇을 대신하고 있는지 가 보입니다.

형식

/root/work/api/app.mjs 를 만들고 아래를 export 합니다.

소켓을 열지 않는 이유는 채점이 포트 충돌이나 기동 타이밍에 흔들리면 안 되기 때문입니다. 실패가 진짜 실패를 뜻해야 시험이 쓸모 있습니다.

서버의 뼈대를 세운다

mkdir -p /root/work/apiapp.mjsexport async function handle(req) 를 두세요. req 는 {method, path, body, headers} 이고, 돌려줄 것은 {status, body} 입니다. /healthz 는 200 과 {status:'ok'}.

handle('/healthz') 이 200 과 {status:'ok'} 를 돌려줍니다

라우팅 표를 만든다 — 404 와 405 를 가른다

경로 목록을 배열로 두고, 먼저 경로가 맞는 것을 모은 뒤 메서드를 봅니다. 경로가 없으면 404, 경로는 있는데 메서드가 없으면 405. GET /items 는 배열을 돌려줍니다.

없는 경로는 404, 있는 경로의 다른 메서드는 405

입력을 검증하고 왜 틀렸는지 알려 준다

POST /items{name: string, qty: number} 를 받습니다. 틀리면 400 과 {errors:[...]}어느 필드가 왜 틀렸는지 담으세요. 정상이면 201.

qty 가 문자열이면 400 과 errors 에 qty, 정상이면 201

저장한 모양과 내보내는 모양을 가른다

저장소에는 secret 이 있지만 응답에는 없어야 합니다. 핸들러마다 지우지 말고 내보낼 필드를 한곳에서 고르세요 — 허용 목록입니다.

GET /items 응답에 secret 이 없고 id·name·qty 는 있습니다

없는 것에는 404 를 준다

GET /items/:id 를 만듭니다. 없으면 404. 200{error:...} 를 담으면 클라이언트가 성공으로 읽습니다 — 상태 코드가 계약입니다.

없는 id 는 404, 있는 id 는 200 과 그 항목

저장소를 주입으로 받는다

export function createApp({store}) 를 만들고 핸들러가 그 store 만 쓰게 하세요. 전역을 직접 참조하면 다음 단계에서 갈아 끼울 수 없습니다.

createApp({store}) 에 넣은 저장소가 실제로 쓰이고 출력 모양도 유지됩니다

이벤트 루프를 막지 않는다

GET /slow 를 만들되 최소 40ms 는 걸리게 하세요. while 로 시간을 태우면 그동안 타이머까지 멈춥니다. await new Promise(r => setTimeout(r, 50)) 로 양보하세요.

네 요청을 동시에 처리하는 동안 5ms 타이머가 계속 돕니다

서버를 띄우지 않고 계약을 시험한다

app.test.mjsnode --test 로 도는 시험을 두 건 이상 쓰세요. createApp 으로 가짜 저장소를 주입해 시험합니다 — 포트를 열면 안 됩니다.

node --test 가 2건 이상 통과하고 서버를 띄우지 않습니다