REST란?
: HTTP를 기반으로 클라이언트가 서버의 리소스에 접근하는 방식을 규정한 아키텍처
HTTP URI(Uniform Resource Identifier)를 통해 자원(Resource)을 명시하고, HTTP Method(POST, GET, PUT, DELETE)를 통해 해당 자원에 대한 CRUD Operation을 적용하는 것을 의미
- REST API
:REST를 기반으로 서비스 API를 구현한 것을 의미
- RESTful
:RESTful은 일반적으로 REST라는 아키텍처를 구현하는 웹 서비스를 나타낸다.
→
REST API
를 제공하는 웹 서비스를 RESTful
하다고 할 수 있다.
REST API의 구성
자원
,행위
,표현
의 3가지 요소로 구성- 자원
- 행위
- 표현
: 문서, 이미지와 같은 모든 정보
→ 정보는 JSON, HTML, XLT, Python, 일반 텍스트 등 다양한 형식으로 전달할 수 있으며 가장 자주 사용되는 것은 JSON이다. 사람과 기계가 읽을 수 있고 언어에 구애받지 않기 때문!
→ URI(엔드포인트)
: 자원에 대한 행위
→ HTTP 요청 메서드
: 자원에 대한 구체적인 내용
→ 페이로드: 보내고자 하는 데이터 자체
REST API 설계 원칙
가장 중요한 기본 원칙
- URI는 리소스를 표현하는데 집중
- 행위에 대한 정의는 HTTP 요청 메서드를 통해 진행
- URI는 리소스를 표현해야 한다.
- 동사보다
명사
를 사용 → get과 같은 행위에 대한 표현이 들어가서는 안됨!
#bad GET/getTodos/1 GET/todos/show/1 #good GET/todos/1
- 리소스에 대한 행위는 HTTP 요청 메서드로 표현한다.
const [todo, setTodo] = useState([]); useEffect(() => { fetch(`http://localhost:3000/todos`, { method: "GET", }) .then((res) => { return res.json(); }) .then((data) => setTodo(data)); }, []);
get요청의 경우 method를 생략해도 된다.
const [todo, setTodo] = useState([]); useEffect(() => { fetch(`http://localhost:3000/todos/1`, { method: "GET", }) .then((res) => { return res.json(); }) .then((data) => setTodo(data)); }, []);
이렇게 id를 사용하여 특정 todo를 취득할 수 있다.
POST 요청
POST요청을 보내는 경우 페이로드의 MIME 타입을 지정해야 한다.
MIME 타입이란? : 데이터 유형을 식별하는 사용되는 레이블이다. →인터넷에서 파일 유형을 분류하는 표준 방식을 형성한다. → 바이너리 데이터를 아스키코드로 인코딩
MIME 타입을 사용하는 이유
이전에는
UUEncode
방식을 사용하였다. 예전에는 텍스트 파일을 주고받는데 ASCII로 공통된 표준에 따르면 문제가 없었다. 하지만 네트워크를 통해 ASCII 파일이 아닌 바이너리 파일을 보내는 경우가 생겼다.(음악, 영상, 워드 등…)
이러한 바이너리 파일은 ASCII만으로 전송이 불가능하며 텍스트 파일로의 변환이 필요하게 되었고 MIME
으로 인코딩한 파일은 Content-Type 정보를 파일 앞부분에 담게 된다.
Content-Type 이란?
MIME 실체가 인코딩하고 있는 데이터의 종류를 설명onSubmit = () => { fetch(`http://localhost:3000/todos`, { method: "POST", headers: { "content-Type": "application/json", }, body: JSON.stringify({ content: content, }), }) .then((res) => { if (res.ok) { //POST가 성공했을 때의 로직 } }) .catch((error) => { //실패했을 때의 로직 }); };
PUT 요청
PUT 요청의 경우 id로 특정하여 id를 제외한 리소스 모두 교체한다.
만약 보내지 않은 값이 있다면 null로 변한다.
const onUpdate = () => { fetch(`http://localhost:3000/todos/1`, { method: "PUT", headers: { "content-Type": "application/json", }, body: JSON.stringify({ content: content, }), }) .then((res) => { if (res.ok) { //성공했을 경우 로직 } }) .catch((error) => { //실패했을 경우 로직 };
PATCH 요청
특정 리소스의 일부를 수정할 때 사용
const onUpdate = () => { fetch(`http://localhost:3000/todos/2`, { method: "PATCH", headers: { "content-Type": "application/json", }, body: JSON.stringify({ completed: true, }), }) .then((response) => response.json()) .then((data) => console.log(data)); };
DELETE 요청
id를 사용하여 todo를 삭제한다.
const onUpdate = () => { fetch(`http://localhost:3000/todos/3`, { method: "DELETE", }) .then((response) => response.json()) .then((data) => console.log(data)); };