Skip to content

사용방법

https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch

스펙

- GET
  - JSON
  - HTML
  - TXT
- POST
  - JSON
  - File Upload
- PUT
  - JSON
  - File Upload
- DELETE

예제

도메인 변경

/src/fetch-wrapper.js 상수 변경 후 사용

js
const DOMAIN = 'http://localhost:3000'

응답 포맷

{
  body: <HTTP Body>,
  status: <Status Code>,
  statusText: <Status Message>, 
}

GET

Basic
js
fetchGetData('/get/json', { value: 10 })
  .then(response => console.log(response))
fetchGetData('/get/text')
  .then(response => console.log(response))
Image
js
fetchGetData('/static/code.png')
  .then(response => {
    getElem('get-image-tag').src = URL.createObjectURL(response.body)
  })

POST

Basic
js
fetchPostData('/post/json', {data: 'json'})
  .then(response => console.log(response))
File Upload
js
const file = getElem('post-file-input').files[0]
const formData = new FormData()
formData.append('uploadFile', file, file.name)

fetchPostData('/post/file', formData)
  .then(response => console.log(response))

PUT

Basic
js
fetchPutData('/put/json', {data: 'json'})
  .then(response => console.log(response))
File Upload
js
const file = getElem('put-file-input').files[0]
const formData = new FormData()
formData.append('uploadFile', file, file.name)

fetchPutData('/put/file', formData)
  .then(response => console.log(response))

DELETE

Basic
js
fetchDeleteData('/delete/json', {data: 'json'})
  .then(response => console.log(response))

fetch-wrapper.js

js
const DOMAIN = 'http://localhost:3000'
const DEFAULT_HEADER = {
  'Content-Type': 'application/json'
}

const HTTP_METHOD = {
  GET: 'GET',
  POST: 'POST',
  PUT: 'PUT',
  DELETE: 'DELETE'
}

const fetchGetData = (url, queryObj) => {
  return fetchData({
    url: `${url}${queryToString(queryObj)}`,
    method: HTTP_METHOD.GET
  })
}

const fetchPostData = (url, body) => {
  return fetchData({
    url,
    body,
    method: HTTP_METHOD.POST,
  })
}

const fetchPutData = (url, body) => {
  return fetchData({
    url,
    body,
    method: HTTP_METHOD.PUT,
  })
}

const fetchDeleteData = (url, body) => {
  return fetchData({
    url,
    body,
    method: HTTP_METHOD.DELETE,
  })
}

const fetchData = ({url, method, body, headers}) => {
  return fetch(`${DOMAIN}${url}`, {
    method,
    body: toHttpBody(body),
    headers: toHttpHeader({body, headers})
  })
    .then(async response => {
      const {status, statusText} = response
      const body = await extractHttpBody(response)
      return {status, statusText, body}
    })
}

const toHttpBody = body => {
  return isFormData(body) ? body : JSON.stringify(body)
}

const toHttpHeader = ({body, headers}) => {
  return isFormData(body) ? undefined : Object.assign(DEFAULT_HEADER, headers)
}

const extractHttpBody = response => {
  const contentType = response.headers.get('Content-Type')

  switch (true) {
    case contentType.startsWith('application/json'):
      return response.json()
    case contentType.startsWith('image'):
      return response.blob()
  }
  return response.text()
}

const isFormData = data => data instanceof FormData

const queryToString = obj => {
  if (!obj) {
    return ''
  }

  const query = Object
    .entries(obj)
    .map(item => item.join('='))
    .join('&')
  return `?${query}`
}