이번 주 비대면에서는 클로저, Promise, async/await를 배웠습니다. 이 문법들이
실제 웹에서 가장 많이 쓰이는 곳은 서버와 통신할 때입니다.
오늘은 fetch 문법을 다시 외우는 시간이 아니라, API를 팀 사이의 계약으로 보는
감각을 잡아보겠습니다.
프론트엔드 입장에서 API는 "서버에서 데이터를 받아오는 주소"처럼 보입니다. 하지만 팀 관점에서 API는 훨씬 중요합니다. 프론트엔드와 백엔드가 서로 기대하는 데이터의 모양, 에러의 형태, 권한 규칙, 페이지네이션 방식이 모두 API에 담깁니다.
GET /api/studies?page=1&size=20
이 요청 하나에도 많은 약속이 들어있습니다. page는 0부터 시작하는지 1부터 시작하는지, size 최대값은 얼마인지, 로그인이 필요할지, 실패하면 어떤 에러가 올지, 빈 목록이면 어떤 응답이 올지 정해야 합니다.
{
"items": [
{
"id": 1,
"title": "프론트엔드 스터디",
"status": "OPEN"
}
],
"page": 1,
"totalCount": 42
}
프론트엔드는 이 응답을 화면으로 바꿉니다. 그래서 백엔드가 내려주는 필드 이름과
화면에서 필요한 정보가 맞아야 합니다. status: "OPEN"을 "모집 중"으로
보여줄지, 버튼 노출 조건으로 쓸지 같은 판단도 필요합니다.
성공 응답보다 더 중요한 것이 에러 응답입니다. 실제 서비스에서는 실패가 자주 일어납니다. 네트워크가 끊기고, 권한이 없고, 입력값이 틀리고, 서버가 죽습니다.
{
"code": "STUDY_ALREADY_CLOSED",
"message": "이미 마감된 스터디입니다."
}
에러가 이렇게 내려오면 프론트엔드는 사용자에게 적절한 메시지를 보여줄 수 있습니다. 반대로 모든 에러가 그냥 500으로만 내려오면, 화면에서는 "알 수 없는 오류" 말고 할 수 있는 게 없습니다.
API 협업에서 자주 빠지는 것이 빈 상태입니다. 데이터가 없을 때 빈 배열을 줄지, null을 줄지, 404로 볼지, 정상 응답으로 볼지 합의해야 합니다.
이들은 모두 화면이 다릅니다. 그래서 API 응답과 UI 상태를 함께 설계해야 합니다.
목록 API에서는 페이지네이션이 거의 항상 등장합니다. 이때 offset 방식인지 cursor 방식인지, 정렬 기준은 무엇인지, 다음 페이지가 있는지 어떻게 알려줄지 정해야 합니다.
작은 프로젝트에서는 별것 아닌 것처럼 보여도, 무한 스크롤이나 검색 필터가 붙으면 이 결정이 사용자 경험과 성능을 크게 좌우합니다.
CORS는 처음 보면 백엔드 에러처럼 보이지만, 사실 브라우저의 보안 정책입니다. 다른 출처의 API를 마음대로 호출하지 못하게 막는 규칙입니다.
프론트엔드 개발자가 CORS를 알아야 하는 이유는, 이 문제가 생겼을 때 "프론트에서 코드 조금 바꾸면 되겠지"가 아니라 서버의 응답 헤더와 배포 환경을 함께 봐야 하기 때문입니다.
Swagger, Postman, Notion 문서 같은 API 문서는 단순 참고 자료가 아닙니다. 프론트와 백엔드가 같은 그림을 보고 있는지 확인하는 협업 도구입니다.
스터디 목록 화면에서 모집 중/마감 상태에 따라 버튼이 달라집니다.
응답에 status 필드를 OPEN/CLOSED 형태로 받을 수 있을까요?
빈 목록일 때는 items: []와 totalCount: 0으로 내려오는지 확인 부탁드립니다.
이렇게 질문하면 백엔드도 무엇을 맞춰야 하는지 명확해집니다. 좋은 프론트엔드 개발자는 화면 요구사항을 API 계약 언어로 바꿔 말할 수 있어야 합니다.
다음 대면에서는 웹 보안을 다룹니다. 특히 브라우저에 있는 코드는 사용자가 볼 수 있고 조작할 수 있다는 전제에서, 프론트엔드가 어디까지 믿어도 되는지 이야기합니다.