what is Request? | API
사용자가 웹 페이지에 처음 접속하는 과정을 정리해 보자.
- client가 주소창을 이용해서 HTTP request로 URL을 요청한다.
- URL에 해당하는 server가 html, css, js 파일을 Client에게 전달한다.
- client의 브라우저가 해당 파일들을 rendering해서 client에게 보여준다.
웹 페이지에 접속한 뒤에도 사용자는 다양한 요청을 할 수 있다. 무언가를 검색할 수도 있고, 마음에 드는 검색 결과가 나올 때 까지 스크롤을 내릴 수도 있다. 이 때 사용자는 주소창에 새로운 url을 입력하지 않는다. 즉, 사용자가 직접 어떤 요청을 하지않더라도 새로운 데이터를 볼 수 있다. 내가 검색한 키워드에 맞는 추천 검색어 목록, 스크롤을 끝까지 내렸을 때 보여지는 새로운 컨텐츠(infinite scroll)가 이런 데이터의 일종이다.
이런 데이터는 새로운 html, css, js 파일이 아니다. 자바스크립트 파일 안에서 특정 API를 이용해 원하는 데이터를 요청하는 코드가 있고, 받아온 데이터를 DOM 요소를 조작해서 보여주고 있는 것이다.
- API | Application Programming Interface
- API는 매우 광범위한 용어로, 어떤 소프트웨어가 다른 소프트웨어 프로그램과 상호작용(resource 주고 받기 등) 할 수 있도록 해주는 인터페이스를 의미한다.
- 웹 개발자들이 사용하는 API라는 용어는 주로 Web API를 가리키며, 이는 HTTP를 기반으로 하는 interface를 말한다.
- API의 종류는 매우 많고, 할 수 있는 일도 다양하다.
- web API에 요청을 함으로써 원하는 데이터를 받아오는 것이 가장 흔함
- 새로운 글을 post하는 일을 수행할 수도 있음, 예를 들어 instagram에는 자신이 mention된 포스트/댓글에 자동으로 댓글을 달아주는 api도 있음
- weather API, twilio API(자동 메세지 등)
what is response? | JSON
JSON은 오직 데이터만을 저장하기 위해 만들어진 파일 포맷으로, 오늘날 대부분의 request에 응답하는 데이터가 json 포맷에 담겨져 있다.
아래의 코드를 보면 JSON 파일에 어떤 식으로 데이터가 작성되는지 볼 수 있다. 마치 객체 데이터의 key와 value같다. 실제로 JSON은 JavaScript Object Notation의 약자로, 자바스크립트 객체 표기법에서 영감을 받은 파일의 형식이라, JSON이라는 이름이 붙었다. 그래서 json 파일의 데이터를 객체로 오해하기 쉽지만, 문자열이다. 이런 json은 자바스크립트 객체로 변환할 수도 있고, 객체 또한 json으로 변환할 수 있다.
- XML | eXtensible Markup Language, json 이전에 가장 보편적으로 사용되던 데이터 저장 파일 포맷
- AJAX | Asynchronous Javascript And XML, 자바스크립트를 이용해 비동기적으로 데이터를 받아오거나 보내는 것을 의미
{
"items" : [
{"type": "tshirt", "color": "red"},
{"type": "skirt", "color": "white"},
{"type": "pants", "color": "yellow"},
]
}
format
JSON 형식에서 지켜야 할 몇가지 사항이 있다(json format이 유효한지 확인할 수 있는 사이트).
- key 값은 반드시 double quote로 감싸야 한다(single quote❌)
- value 값의 데이터 형식은 string, number, object, array, boolean, null을 사용할 수 있다(undefined ❌).
method
- JSON.stringify( 객체 ) | 객체를 JSON으로 변환(serialize)
- js 객체 데이터를 서버에 보내기 전에 stringify를 이용하여 문자열로 변환한다
- stringify를 이용해서 객체 me를 문자열 json으로 반환할 때 객체의 메서드는 포함되지 않는다. 객체의 프로퍼티, 즉 상태 데이터 만이 포함된다.
- JSON.parse( JSON ) | JSON을 객체로 변환(de-serialize)
- 서버가 보낸 json 문자열 데이터를, parse를 이용해서 객체로 변환한다
- +) 브라우저가 제공하는 fetch API를 이용해서 받아온 데이터를 json() 함수를 이용해 객체로 변환하는 것과 같은 개념이다.
const me = {
name : 'jurassic',
age : 23,
eat : () => {
console.log('eat');
}
};
const json = JSON.stringify(me);
const obj = JSON.parse(json);
obj;
/*
{name: 'jurassic', age: 23}
*/
json;
/*
'{"name":"jurassic","age":23}'
*/
- GET | request method의 하나로, 데이터를 받아오는 API를 의미
- POST, DELETE, PATCH 등 다양한 요청 타입이 있다.
- Body | body of the response, 요청한 데이터 또는 컨텐츠 파일이 담겨있는 곳
- Status | 요청과 응답에 대한 상태가 담겨있음
- 200번대 코드 | 요청과 응답 모두 성공했음을 의미
- 400번대 코드 | client error, api 요청에 문제가 있음을 의미
- 500번대 코드 | server error, 서버의 응답에 문제가 있음을 의미
- Headers | 요청과 응답이 각각 가지고 있는 metadata
How to make request?
XHR | XMLHttpRequest
자바스크립트 코드를 이용해서 특정 api에 요청을 보내는 초기의 방식으로, promise를 지원하지 않기 때문에 수 많은 콜백함수들을 이용해야 한다.
const req = new XMLHttpRequest();
req.onload = function () {
console.log('request sucess!');
console.log('this:', this); // req
/*
const data = JSON.parse(this.responseText);
*/
};
req.onerror = function () {
console.log('request fail!');
};
req.open('GET', 'https://api.tvmaze.com/search/shows?q=girls');
req.send();
/*
request sucess!
this: XMLHttpRequest {
...,
onabort: null,
onerror: ƒ (),
onload: ƒ (),
onloadend: null,
onloadstart: null,
onprogress: null,
onreadystatechange: null,
ontimeout: null,
response: "[{\"score\":0.9093585,\"show\":{\"id\":139,\"url\...,
responseURL: "https://api.tvmaze.com/search/shows?q=girls",
status: 200,
...
}
*/
fetch
자바스크립트 코드를 이용해서 api 요청을 보내는 최신 방식으로, promise 객체를 지원하기 때문에 수많은 콜백함수를 이용하지 않아도 된다. fetch 함수를 실행하면 함수는 promise를 반환하는데, fulfilled 상태일 때 Response라는 객체를, rejected 상태일 때 에러를 각각 result로 업데이트 한다. 이에 따라, then과 catch method를 이용해서 원하는 함수를 실행할 수 있다.
fetch('https://api.tvmaze.com/search/shows?q=girls');
/*
Promise {<fulfilled>}
[[Prototype]]: Promise
[[PromiseState]]: "fulfilled"
[[PromiseResult]]: Response
body: ReadableStream, // ✅ no data here!
headers: Headers {},
...,
ok: true,
status: 200,
type: "cors",
url: "https://api.tvmaze.com/search/shows?q=girls"
*/
그런데 fetch는 모든 데이터가 도착해야 resolve를 실행하는 게 아니라, header 부분만 도착해도 resolve를 실행하기 때문에, state가 fulfilled이 된 시점에서 body 부분에 우리가 요청한 데이터는 담겨있지 않다. 이 때 필요한 것이 json이라는 메서드인데, JSON.parse와는 다르다, promise 객체를 반환하며, body 부분의 데이터가 전부 성공적으로 도착하면, 자바스크립트 객체로 변환된 데이터를 result로 갖는다.
fetch('https://api.tvmaze.com/search/shows?q=girls')
.then(response => response.json()) // return promise
.then(data => console.log(data))
.catch(e => console.log(e))
// async await
const getTVShow = async () => {
try {
const response = await fetch('https://api.tvmaze.com/search/shows?q=girls');
const data = await response.json();
console.log(data);
} catch(error) {
console.log(error)
}
};
Axios | http request를 fetch보다 쉽게 만들어주는 라이브러리
- axios.get
- fetch에서 사용한 것처럼 api에 데이터를 요청할 수 있다.
- 이 때 fetch와는 달리 한 번의 요청으로 body에 포함된 모든 데이터를 객체 타입으로 받아온다.
- 즉, response.json() 과정을 거치지 않아도 된다.
axios.get("https://api.tvmaze.com/search/shows?q=girls");
/*
[[Prototype]]: Promise
[[PromiseState]]: "fulfilled"
[[PromiseResult]]: Object
, ...,
data: (10) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}],
headers: {cache-control: 'public, max-age=3600', content-type: 'application/json; charset=UTF-8'},
request: XMLHttpRequest {onreadystatechange: null, readyState: 4, timeout: 0, withCredentials: false, upload: XMLHttpRequestUpload, …},
status: 200,
...
*/
axios
.get('https://api.tvmaze.com/search/shows?q=girls')
.then( response => console.log(response.data))
.catch( error => console.log(error));
- api에 따라 request의 header에 포함될 값을 따로 셋팅(configuration)해야 하는 경우도 있다.
- ex) content type(html, json, xml...)을 결정해야 하거나, api key를 설정해야 하는 경우 등
- => random jokes api
const config = {
headers: {
Accept: 'application/json',
'X-RapidAPI-Host': 'dad-jokes.p.rapidapi.com',
'X-RapidAPI-Key': 'key here',
}
}
const response = await axios.get('https://dad-jokes.p.rapidapi.com/random/joke', config);
- api에 요청을 할 때, query string(어떤 요청을 할 것인지에 대한 구체적인 정보)를 수동적으로 입력하는 것이 아니라, params에 전달함으로써 자동으로 api에 추가되도록 만들 수 있다.
async function fetchTVShow(input) {
const config = { params: { q: input } };
const result = await axios.get(`https://api.tvmaze.com/search/shows`, config);
return result.data.map((tvshow) => tvshow.show.name);
}
'Study > JavaScript' 카테고리의 다른 글
Hoisting (0) | 2022.05.25 |
---|---|
Var (0) | 2022.05.25 |
This (0) | 2022.04.05 |
OOP | Prototype, Class (0) | 2022.04.05 |
Scope, Execution context, Closure (0) | 2022.04.04 |