이 특징은 서버가 상태 정보를 저장하거나, 추적할 필요가 없다는 것이다.
이러한 특징으로 서버를 100개 넘게 확장하여도 상태 관리를 해줄 필요가 없기때문에 확장시 부담이 줄게된다.
왜냐하면 클라이언트는 서버에 요청을 보낼 때 매번 지금 요청이 처음인것처럼 상태 정보를 담아서 보내주기 때문이다.
HTTP 와는 다르게 연결상태를 유지하는 FTP(파일 전송 프로토콜) 응용 계층 프로토콜이 존재한다.
StatefFul
손님: 아이스 아메리카노 얼마인가요?
스벅 직원: 5000원 입니다.
손님: 2개 주세요.
스벅 직원: 10000원 입니다. 결제는 무엇으로 하시겠습니까?
손님: 기프티콘이요.
스벅 지원: 결제 완료 되었습니다.
Stateless
손님: 아이스 아메리카노 얼마인가요?
스벅 직원: 5000원 입니다.
손님: 2개 주세요.
스벅 직원: 무엇을 2개 달라는 거죠?
확장성이 좋다는 장점이 있지만, 모든 요청에 정보를 담아서 보내야 하므로 요청 패킷에 헤더정보가 많아진다는 단점이 존재한다.
Wireshark는 네트워크 패킷 분석 프로그램이다.
네트워크 통신을 캡처하여 모니터링 할 수 있다.
무료이고, GUI도 깔끔하여 초보자도 쉽게 사용할 수 있다.
프로토콜 분석, 개발, 교육에 다양하게 쓰인다.
const res = await fetch(uri, {
headers: {
"Content-Type": "application/json",
Accept: "application/json",
},
});
const data = await res.json();
HTTP에는 다양한 헤더가 존재한다.
이 중에서 자주 사용되는 헤더를 직접 응용하는 케이스를 작성해보았다.
Authorization
인증 토큰을 서버로 보낼 때 사용하는 헤더이다.
깃허브 API를 사용하는 경우 인증 토큰을 실어 요청을 보내지 않으면 시간당 60회로 요청이 제한된다.
async function request(uri) {
const response = await fetch(uri, {
headers:{
'Authorization': 'token ' + GITHUB_ACCESS_TOKENS
}
});
return response.json();
}
request(`https://api.github.com/users/${username}${defaultParams}`);
If-None-Match
ETag: "33a64df551425fcc55e4d42a148795d9f25f89d4
클라이언트에서는 이 헤더를 통해 캐시를 이용할 수 있는 명분을 만들 수 있다.
캐시를 이용하여 서버와의 통신을 효율적으로 이용하여 웹 성능을 높일 수 있다.
말이 어려웠다.. 예시를 통해 어떤 느낌인지만 이해해도 나중에 문서를 찾아보고 사용할 때 도움이 될것이라 생각한다.
Youtube API를 통한 예시를 살펴보자
시작하기 | YouTube Data API | Google Developers
export const searchVideo = async (id) => {
const YOUTUBE_URL = `https://www.googleapis.com/youtube/v3/videos?key=${YOUTUBE_API_KEY}&part=snippet&id=${id}`;
const res = await fetch(YOUTUBE_URL, {});
const data = await res.json();
return data;
};
위에서 보는것과 같이 특정 ‘videoId’에 관한 정보를 요청해서 받았을 때 응답에 ‘etag’가 존재하는 것을 알 수있다.
하지만, 이렇게 계속 요청을 보낸다면 해당 비디오의 정보가 바뀌지 않았는데도 불구하고, 사용자가 해당 비디오를 클릭했을 때 서버는 계속 동일한 응답을 줄 것이다.
리소스가 바뀌지 않았는데 동일한 요청-응답을 주고받는 것이 매우 비효율적으로 보인다.
이제 요청을 보낼 때 이전에 응답으로 받은 eTag를 이용하여 ‘If-none-Match'헤더에 값으로 설정해주고, 두번째 요청을 보내보자.
export const searchVideo = async (id, eTag) => {
const YOUTUBE_URL = `https://www.googleapis.com/youtube/v3/videos?key=${YOUTUBE_API_KEY}&part=snippet&id=${id}`;
const res = await fetch(YOUTUBE_URL, {
headers: {
"If-None-Match": eTag,
},
});
const data = await res.json();
return data;
};
아직 침착맨이 해당 비디오를 업데이트 하지 않았기 때문에 YouTube API 서버에서는 해당 비디오에 관한 동일한 ‘eTag’를 가지고 있으므로, ‘304 응답코드(Not Modified)’를 보냈다.
그럼 이제 클라이언트 단에서 첫번째 요청에 대한 응답을 캐싱하여 사용자가 다시 동일한 비디오를 클릭했을 때 ‘‘304 응답코드(Not Modified)’을 확인하고, 캐싱된 데이터를 활용하여 사용자에게 보여주면 될 것이다.
실제로 리소스의 캐시를 검증을 위해 17바이트만의 네트워크 송수신을 주고받을 것을 볼 수 있다.
지금까지 HTTP를 평소보다 조금 더 살펴보았다.
HTTP가 무엇이고, 실제 HTTP가 단순히 HEX 데이터로 이루어진 것을 눈으로 확인했다.
또, HTTP 헤더 중 ‘Authorization
', ‘If-None-Match
'를 어떻게 사용할 수 있는지 직접 테스트 해보았다.
HTTP에 기본적인 내용들은 MDN, 개인 블로그에 자세하게 설명되어 있으므로 찾아보면 방대하게 나올 것이다.
우리가 자바스크립트를 통해 보내는 HTTP 요청과 응답의 내면이 어떤식으로 이루어졌는지 알면 나의 코드를 더 넓게 볼 수 있는 힘을 가질 수 있다고 생각해 이 자료를 정리해보았다.
HTTP 최근 트렌드에 대해 더 알고싶다면 파이프라인을 통해 하나의 세션에서 여러 요청을 보낼 수 있는HTTP2(SPDY), TCP 프로토콜보다 빠른 UDP 전송 계층 프로토콜 위에서 사용되는 HTTP3(QUIC)에 대해 살펴보면 좋을 거 같다.
Hands-On RESTful API Design Patterns and Best Practices
HTTP(HyperText Transfer Protocol)의 특징
[HTTP] HTTP 특성(비연결성, 무상태)과 구성요소 그리고 Restful API