Front-End/JavaScript

[JavaScript] HTTP 메소드 (Feat. fetch)

시니철 2024. 9. 25. 09:21

HTTP 메소드란?

HTTP 메소드란 웹에서 클라이언드(브라우저)와 서버 간의 통신을 정의하는 방법이며, method 옵션은 요청의 유형을 지정하며, `GET`, `POST`, `PATCH`, `DELETE` 등의 값을 가질 수 있고, method를 지정하지 않으면 기본 값은 `GET`입니다.

 

`GET` : 서버로부터 데이터를 요청할 때 사용

`POST` : 서버에 데이터를 전송할 때 사용

`PUT` : 서버의 기존 리소스를 업데이트하거나 새로운 리소스를 생성할 때 사용

`DELETE` : 서버에서 특정 리소스를 삭제할 때 사용

`PATCH` : 리소스의 부분적인 업데이트를 수행할 때 사용


`fetch()` 기본 문법

const res = await fetch('url');

// 리스폰스 상태 코드
res.status;

// 리스폰스 헤더
res.headers;

await res.json(); // JSON 문자열을 파싱해서 자바스크립트 객체로 변환
await res.text(); // 문자열을 그대로 가져옴

 

`res.json()` 메소드는 바디의 JSON 문자열을 파싱해서 자바스크립트 객체로 변환해 주고 `res.text()` 메소드는 바디의 내용을 문자열로 그대로 가져옵니다. 따라서 바디의 내용이 JSON 형식이 아닌데 `res.json()` 메소르를 사용하면 오류가 발생합니다.

 

`fetch()` 사용 예시

const res = await fetch('url');
const data = await res.json();

console.log(data);

 

`fetch` 함수를 사용하여 주어진 `URL`에서 데이터를 비동기적으로 요청하고, 응답을 JSON 형식으로 변환한 후, 그 결과를 콘솔에 출력합니다.

 

fetch() 참고

 

[JavaScript] Promise 정리 (fetch, async, await, then)

Promise란?비동기 작업이 완료되면 값을 알려 주는 객체이고, 작업이 완료되면 값을 알려줄 것을 약속하기 때문에 이름이 Promise 입니다. Promise 객체는 세 가지 상태로`Panding` : 비동기 작업이 끝나

hwiiron.tistory.com


URL 객체

const params = { offset: 10, limit: 10 };
const url = new URL('url');

Object.keys(params).forEach((key) => url.searchParams.append(key, params[key]));

const res = await fetch(url);
const data = await res.json();

console.log(data);

 

URL을 다루고 조작할 수 있는 JavaScript의 내장 객체입니다. 쿼리 파라미터를 동적으로 추가하여 URL을 생성하고, URL 생성자를 사용하여 해당 URL을 객체로 변환한 후, `searchParams.appern()` 메소드로 파라미터를 URL에 추가합니다.

이렇게 만들어진 URL을 `fetch` 함수로 요청하고, 응답 데이터를 JSON으로 변환하여 처리합니다.

쿼리 파라미터란 URL 끝에 붙는 추가 정보로, `?key=value` 형태로 표현되고, 서버에 요청을 보낼 때 특정 데이터를 전달하기 위해 사용됩니다.


GET 리퀘스트

`GET` 리퀘스트는 서버에서 데이터는 요청할 때 사용합니다. 클라이언트는 서버로부터 데이터를 읽어오기 위해 주로 GET 요청을 보내며, 이때 데이터를 요청하기 때문에 GET 요청에는 보통 body를 포함하지 않습니다.

fetch('https://hwiiron.com/api/GET?name=시니철&age=27', {
    method: 'GET', // GET은 기본 값이므로 method를 명시하지 않아도 됩니다.
});

 

`GET` 요청의 가장 큰 특징 중 하나는 데이터를 URL에 쿼리 파라미터 형태로 전달하는 점입니다. 또, `fetch` 함수에서 `GET` 요청은 기본 값이므로 두 번째 인자로 `method: 'GET'`을 명시하지 않아도 됩니다.

 


POST 리퀘스트

`POST` 리퀘스트는 서버에 새로운 리소스를 생성하거나, 데이터를 전송할 때 사용됩니다. `fetch` 함수의 두 번째 인자로 다양한 옵션을 넘겨줄 수 있습니다. 그 중 POST 리퀘스트를 보낼 때는 주로 `body`에 데이터를 함께 전달합니다. `body`는 옵션으로 설정 가능하며, 데이터를 전송할 때 자바스크립트 객체를 직접 사용하지 않고 JSON 문자열로 변환하여 전송하는 것이 중요합니다.

const info = {
    name: '시니철',
    age: '27',
};

fetch('https://hwiiron.com/api/POST', {
    method: 'POST',
    body: info, // 리퀘스트 body에 데이터를 설정 가능
});

 

위 코드에서 `info`는 자바스크립트 객체입니다. 하지만 외부 서버로 데이터를 주고 받을 때는 `JSON.stringify()`를 사용하여 JSON 문자열 형식으로 전달해야 합니다. 

const info = {
    name: '시니철',
    age: '27',
};

fetch('https://hwiiron.com/api/POST', {
    method: 'POST',
    body: JSON.stringify(info), // JSON 문자열로 변환
});

 

또한, 데이터를 전송할 때는 서버에 어떤 형식의 데이터를 보내는지 알려주기 위해 `Content-Type` 헤더를 설정하는 것이 좋습니다. 주로 `application/json` 형식의 사용해 서버가 JSON 형식으로 데이터를 처리할 수 있도록 합니다.

 

fetch('https://hwiiron.com/api/POST', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' }, // 데이터 형식 명시
    body: JSON.stringify(info), // JSON 문자열로 변환
});

 

이렇게 서버가 클라이언트로부터 전송된 JSON 데이터를 처리할 수 있습니다.


PATCH 리퀘스트

`PATCH` 리퀘스트는 서버의 리소스 일부를 업데이트 할 때 사용됩니다. 예를 들어, 이름만 업데이트 하고 싶을 때 `PATCH` 요청을 사용하여 일부 정보만 서버에 전달할 수 있습니다.

const updateData = {
    name: '은주',
};

fetch('https://hwiiron.com/api/PATCH',
    method: 'PATCH',
    headers: {
        'Content-Type': 'application/json', // 데이터 형식 명시
    },
    body: JSON.stringify(updateData), // 업데이트 할 데이터 정보 전송
});

DELETE 리퀘스트

`DELETE` 리퀘스트는 서버에서 특정 리소스를 삭제할 때 사용됩니다. 보통 `DELETE` 요청에서는 body를 포함하지 않지만, 만약 특정 데이터를 전송해야 할 경우에는 body를 설정할 수 있습니다. 

const deleteData = {
    id: '1234',
};

fetch('https://hwiiron.com/api/DELETE', {
    method: 'DELETE',
    headers: {
        'Content-Type': 'application/json', // 데이터 형식 명시
    },
    body: JSON.stringify(deleteData), // 삭제할 데이터 정보 전송
});

 

위 코드에서 `id: '1234'`라는 데이터를 서버로 보내 특정 리소스를 삭제합니다. bodyJSON 형식으로 변환 후 전송해야 하며, `Content-Type` 헤더를 설정해 데이터를 명시하는 것이 좋습니다.


API 함수

똑같은 리퀘스트를 보내는 코드가 반복된다면 함수로 만들어 사용하는 것이 좋습니다. 보통은 웹 개발을 할 때 `API`를 호출하는 함수들을 따로 모아두고 필요할 때 `import`해서 사용한다고 합니다.

// GET
export async function getFunc(id) {
	const res = await fetch(`https://hwiiron.com/api/${id}`);
    const data = await res.json();
    return data;
}


// POST
export async function postFunc(postData) {
	const res = await fetch('https://hwiiron.com/api/POST', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' }, // 데이터 형식 명시
        body: JSON.stringify(postData), // JSON 문자열로 변환
    });
    const data = await res.json();
    return data;
}


// PATCH
export async function patchFunc(patchData) {
	const res = await fetch('https://hwiiron.com/api/PATCH', {
        method: 'PATCH',
        headers: {
            'Content-Type': 'application/json', // 데이터 형식 명시
        },
        body: JSON.stringify(patchData), // 업데이트 할 데이터 정보 전송
    });    
    const data = await res.json();    
	return data;
}


// DELETE
export async function deleteFunc(deleteData) {
	const res = await fetch('https://hwiiron.com/api/DELETE', {
        method: 'DELETE',
        headers: {
            'Content-Type': 'application/json', // 데이터 형식 명시
        },
        body: JSON.stringify(deleteData), // 삭제할 데이터 정보 전송
    });
    const data = await res.json();
    return datal
}

 

리퀘스트마다 바뀔 수 있는 부분을 함수 파라미터 받아서 활용하면 됩니다.


`fetch()` 오류 처리

`fetch` 오류에는 크게 두 가지 경우가 있습니다. 첫 번째는 URL이 잘못되었거나, 헤더 정보가 잘못되어 요청 자체가 실패하는 경우로, `fetch`가 `Rejected` 상태가 되어 오류를 발생시킵니다. 두 번째 요청은 성공적으로 이루어졌지만, 응답의 상태 코드가 실패를 나타내는 경우가 있습니다. 

 

첫 번째 경우는 `fetch` 함수 자체가 실패하여 `Rejected` 상태가 되므로, `try...catch`문으로 잡아낼 수 있지만, 두 번째 경우는 `try...catch`문으로 잡히지 않기 때문에 수동으로 오류를 `throw`해야 합니다.

export async function getFunc(id) {
    const res = await fetch(`https://hwiiron.com/api/${id}`);
    
    if (!res.ok) {
    	throw new Error('데이터를 불러오는데 실패했습니다.');
    }
    
    const data = await res.json();
    return data;
}

`.ok` : 상태 코드가 200~299인 경우 `true`를 반환하고, 그렇지 않으면 `false`를 반환

import { getFunc } from './api.js';

try {
  const data = await getFunc(1234); // 존재하지 않는 id
  console.log(data);
} catch (e) {
  console.log('오류가 발생했습니다:')
  console.log(e.message);
}

// 오류가 발생했습니다:
// 데이터를 불러오는데 실패했습니다.

 

리퀘스트가 완전히 성공하지 않는 이상 오류를 `throw`하기 때문에 쉽게 처리할 수 있습니다.