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이 잘못되었거나, 헤더 정보가 잘못되어 요청 자체가 실패하는 경우로, fetchRejected 상태가 되어 오류를 발생시킵니다. 두 번째 요청은 성공적으로 이루어졌지만, 응답의 상태 코드가 실패를 나타내는 경우가 있습니다. 

 

첫 번째 경우는 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하기 때문에 쉽게 처리할 수 있습니다.