[TIL 3일차]

Grace·2021년 11월 3일
0

코드캠프 TIL

목록 보기
3/34

Status Code

각각의 상태 코드에는 대응되는 상태 메시지가 있습니다.

모든 상태 코드(Status Code)는 각각 그에 대응되는 상태 메시지(Status Message)를 갖고 있습니다.

예를 들어, 200번은 OK, 404번은 Not Found라는 상태 메시지를 갖고 있습니다. 각 상태 코드의 의미를 모두 외우기는 힘들기 때문에 이러한 상태 메시지는 상태 코드의 의미를 빠르게 파악하는데 도움을 줍니다.

상태 코드는 100번대~500번대까지 있어요.

각 번호대는 그것만의 의미를 가지고 있는데요.

100번대
서버가 클라이언트에게 정보성 응답(Informational response)을 줄 때 사용되는 상태 코드들입니다.

  1. 100 Continue : 클라이언트가 서버에게 계속 리퀘스트를 보내도 괜찮은지 물어봤을 때, 계속 리퀘스트를 보내도 괜찮다고 알려주는 상태 코드입니다. 예를 들어, 클라이언트가 용량이 좀 큰 파일을 리퀘스트의 바디에 담아 업로드하려고 할 때 서버에게 미리 괜찮은지를 물어보는 경우가 있다고 할 때, 서버가 이 100번 상태 코드의 리스폰스를 주면 그제서야 본격적인 파일 업로드를 시작합니다.

  2. 101 Switching Protocols : 클라이언트가 프로토콜을 바꾸자는 리퀘스트를 보냈을 때, 서버가 '그래요, 그 프로토콜로 전환하겠습니다'라는 뜻을 나타낼 때 쓰이는 상태 코드입니다.
    200번대
    클라이언트의 리퀘스트가 성공 처리되었음을 의미하는 상태 코드들입니다.

  3. 200 OK : 리퀘스트가 성공적으로 처리되었음을 포괄적으로 의미하는 상태 코드입니다. 이때 성공의 의미는 리퀘스트에 있던 메소드의 종류에 따라 다르겠죠? GET 리퀘스트의 경우 리소스가 잘 조회되었다는 뜻이고, POST 리퀘스트의 경우 새 리소스가 잘 생성되었다, PUT 리퀘스트의 경우 기존 리소스가 잘 수정되었다, DELETE 리퀘스트의 경우 기존 리소스가 잘 삭제되었다는 뜻입니다.

  4. 201 Created : 리퀘스트의 내용대로 리소스가 잘 생성되었다는 뜻입니다. POST 리퀘스트가 성공한 경우에 200번 대신 201번이 올 수도 있습니다.

  5. 202 Accepted : 리퀘스트의 내용이 일단은 잘 접수되었다는 뜻입니다. 즉, 당장 리퀘스트의 내용이 처리된 것은 아니지만 언젠가 처리할 것이라는 뜻인데요. 리퀘스트를 어느 정도 모아서 한번에 실행하는 서버인 경우 등에 이런 응답을 줄 수도 있습니다.

300번대
클라이언트의 리퀘스트가 아직 처리되지 않았고, 리퀘스트 처리를 원하면 클라이언트 측의 추가적인 작업이 필요함을 의미하는 상태 코드들입니다.

  1. 301 Moved Permanently : 리소스의 위치가 바뀌었음을 나타냅니다. 보통 이런 상태 코드가 있는 리스폰스의 헤드에는 Location이라는 헤더도 일반적으로 함께 포함되어 있습니다. 그리고 그 헤더의 값으로 리소스에 접근할 수 있는 새 URL이 담겨있는데요. 대부분의 브라우저는 만약 GET 리퀘스트를 보냈는데 이런 상태 코드가 담긴 리스폰스를 받게 되면, 헤드에 포함된 Location 헤더의 값을 읽고, 자동으로 그 새 URL에 다시 리퀘스트를 보내는 동작(리다이렉션, redirection)을 수행합니다.
  2. 302 Found : 리소스의 위치가 일시적으로 바뀌었음을 나타냅니다. 이 말은 지금 당장은 아니지만 나중에는 현재 요청한 URL이 정상적으로 인식될 것이라는 뜻입니다. 이 상태 코드의 경우에도 보통 그 리스폰스의 헤드에 Location 헤더가 있고, 여기에 해당 리소스의 임시 URL 값이 있습니다. 이 경우에도 대부분의 브라우저들은 임시 URL로 리다이렉션합니다.
  3. 304 Not Modified : 브라우저들은 보통 한번 리스폰스로 받았던 이미지 같은 리소스들을 그대로 내부에 저장하고 있습니다. 그리고 서버는 해당 리소스가 바뀌지 않았다면, 리스폰스에 그 리소스를 보내지 않고 304번 상태 코드만 헤드에 담아서 보냄으로써 '네트워크 비용'을 절약하고 브라우저가 저장된 리소스를 재활용하도록 합니다.

400번대
리퀘스트를 보내는 클라이언트 쪽에 문제가 있음을 의미하는 상태 코드들입니다.

  1. 400 Bad Request : 말그대로 리퀘스트에 문제가 있음을 나타냅니다. 리퀘스트 내부 내용의 문법에 오류가 존재하는 등의 이유로 인해 발생합니다.
  2. 401 Unauthorized : 아직 신원이 확인되지 않은(unauthenticated) 사용자로부터 온 리퀘스트를 처리할 수 없다는 뜻입니다.
  3. 403 Forbidden : 사용자의 신원은 확인되었지만 해당 리소스에 대한 접근 권한이 없는 사용자라서 리퀘스트를 처리할 수 없다는 뜻입니다.
  4. 404 Not Found : 해당 URL이 나타내는 리소스를 찾을 수 없다는 뜻입니다. 보통 이런 상태 코드가 담긴 리스폰스는 그 바디에 관련 웹 페이지를 이루는 코드를 포함하고 있는 경우가 많습니다. 예를 들어, 다음과 같이

    존재하지 않는 URL에 접속하려고 하면 이런 페이지가 보이는 것을 알 수 있습니다.
  5. 405 Method Not Allowed : 해당 리소스에 대해서 요구한 처리는 허용되지 않는다는 뜻입니다. 만약 어떤 서버의 이미지 파일을 누구나 조회할 수는 있지만 아무나 삭제할 수는 없다고 해봅시다. GET 리퀘스트는 허용되지만, DELETE 메소드는 허용되지 않는 상황인 건데요. 그런데 만약 그 이미지에 대한 DELETE 리퀘스트를 보낸다면 이런 상태 코드를 보게될 수도 있습니다.
  6. 413 Payload Too Large : 현재 리퀘스트의 바디에 들어있는 데이터의 용량이 지나치게 커서 서버가 거부한다는 뜻입니다.
  7. 429 Too Many Requests : 일정 시간 동안 클라이언트가 지나치게 많은 리퀘스트를 보냈다는 뜻입니다. 서버는 수많은 클라이언트들의 리퀘스트를 정상적으로 처리해야 하기 때문에 특정 클라이언트에게만 특혜를 줄 수는 없습니다. 따라서 지나치게 리퀘스트를 많이 보내는 클라이언트에게는 이런 상태 코드를 담은 리스폰스를 보낼 수도 있습니다.

500번대
서버 쪽의 문제로 인해 리퀘스트를 정상적으로 처리할 수 없음을 의미하는 상태 코드들입니다.

  1. 500 Internal Server Error : 현재 알 수 없는 서버 내의 에러로 인해 리퀘스트를 처리할 수 없다는 뜻입니다.
  2. 503 Service Unavailable : 현재 서버 점검 중이거나, 트래픽 폭주 등으로 인해 서비스를 제공할 수 없다는 뜻입니다.

이 상태 코드들도 'Web API 설계'시에 결정되어야 하는 요소들입니다. 리퀘스트에 관한 URL과 메소드 종류 뿐만 아니라 리스폰스의 상태 코드 또한 각각의 상황에 알맞은 것들이 설정되도록 설계해야 하는데요. 사실 모든 상황을 세분화해서 매번 거기에 맞는 상태 코드를 넣는 것은 불필요한 작업이 될 수도 있긴 합니다. 그래서 보통은 꼭 사용할 상태 코드들만 추린 다음에 특정 유형의 상황들은 모두 하나의 상태 코드로 나타내는 전략이 주로 활용됩니다.

하지만 그렇다고 해서 서버가 리퀘스트를 잘 처리했든, 실패했든 상태 코드로 항상 200번을 보내버린다거나 하는 것은 매우 좋지 않습니다. 가장 이상적인 것은 존재하는 상태 코드를 최대한 많이 활용하는 것입니다.

더 많은 상태코드(MDN): https://developer.mozilla.org/ko/docs/Web/HTTP/Status

API

하나의 서비스를 만들 때는 프론트엔드 개발자들과 백엔드 개발자들이 모여 '프론트엔드에서 이 URL로 이렇게 생긴 리퀘스트를 보내면, 백엔드에서 이런 처리를 하고 이런 리스폰스를 보내주는 것으로 정합시다'와 같은 논의를 하고, 이런 내용들을 정리한 후에 개발을 시작합니다.
이것을 Web API 설계라고 합니다. API란 Application Programming Interface의 약자로 어느 URL로 어떤 요청(request)를 보냈을 때 무슨 처리가 수행디고 어떤 리스폰스가 오는지에 관해 미리 정해진 규격입니다.

API의 종류

API의 종류에는 rest-API와 graphql-API가 있습니다.
둘 사이에는 몇 가지 차이점이 있는데요.

함수 이름의 차이

rest-API는 API 이름이 마치 홈페이지 주소처럼 생겼습니다.
graphql-API는 API 이름이 일반적인 함수와 같습니다.

응답 결과물의 차이

rest-API는 응답 결과로 back-end 개발자가 만든 함수에서 보내주는 모든 데이터를 받아야만 합니다. 반면에, graphql-API는 back-end 개발자가 만든 함수에서 필요한 데이터만 골라 받을 수 있습니다.

이러한 이유로, 각 API에 전송을 요청하는 담당자도 다릅니다.
rest-API에 요청하는 요청담당자는 axios입니다.
graphql-API에 요청하는 요청담당자는 apollo-client입니다.

요청담당자는 Front-end 에서 설치하는 라이브러리입니다.

graphql은 필요한 데이터만 골라 받을 수 있는 장점이 있어서, 효율적인 통신을 할 수 있습니다.

그럼에도 불구하고, rest를 배워야하는 이유 가 있습니다.
1. 내가 취업한 회사/팀에서 rest를 사용 중일 수 있습니다.
2. 다른 회사에서 제공해주는 API를 사용하는 경우도 있습니다. 예를들면, 카카오로 로그인하기 기능은, 카카오에서 제공해주는 API를 사용해야하는데, 이러한 기능들은 대부분 rest-API로 제공되고 있습니다.

REST-API (axios)

axios
  .get('https://jsonplaceholder.typicode.com/users')
  .then((response) => {
    console.log(response);
  })
  .catch((error) => {
    console.log(error);
  });

이 코드는 axios 패키지에서 제공하는 axios 객체를 사용해서 GET 리퀘스트를 보내고 그 리스폰스를 받는 코드인데요.

axios 객체에서 리퀘스트를 보내는 많은 메소드들이 fetch 함수처럼 Promise 객체를 리턴합니다. 그래서 fetch 함수의 사용법과 비슷한 점이 많은데요.

axios 객체에는 fetch 함수에는 없는 몇 가지 기능 및 장점들이 있습니다.

  • 모든 리퀘스트, 리스폰스에 대한 공통 설정 및 공통된 전처리 함수 삽입 가능
  • serialization, deserialization을 자동으로 수행
  • 특정 리퀘스트에 대해 얼마나 오랫동안 리스폰스가 오지 않으면 리퀘스트를 취소할지 설정 가능(request timeout)
  • 업로드 시 진행 상태 정보를 얻을 수 있음
  • 리퀘스트 취소 기능 지원

axios가 이렇게 fetch에 비해 다양한 기능을 지원하는 것은 맞지만 단점도 있습니다. 바로 별도의 다운로드가 필요한 패키지라는 점이죠.
fetch 함수는 웹 브라우저에서 바로 지원되는 함수이기 때문에 별도로 패키지를 다운로드받지 않아도 되지만,
axios는 별도로 패키지를 다운로드해줘야 합니다.

그래서 axios에서 제공하는 추가 기능이 필요한 경우에는 axios를 쓰고,
그런 기능이 필요하지 않고 별도의 패키지 다운로드를 원하지 않는 경우에는 fetch 함수를 사용합니다.

실무에서는 fetch 이외에 axios도 많이 쓴다는 점,
그리고 axios 또한 리퀘스트를 보내는 주요 메소드들이 Promise 객체를 리턴한다는 점을 기억하세요.

CRUD

CRUD란 Create-Read-Update-Delete의 약자로 데이터베이스 관점에서 데이터에 관한 처리를 나타낸 합성어인데요.
각 메소드는 각 데이터 관련 작업에 이렇게 대응됩니다.

GET → READ

POST → CREATE

PUT → UPDATE

DELETE → DELETE


API 요청 결과 타입(JSON)

fetch('https://jsonplaceholder.typicode.com/users ')
	.then((response) => response.text())
	.then((result) => {console.log(result); });

JSON에는 프로퍼티의 이름과 값을 표현하는 방식에 제한이 있다.

  • JSON에서는 각 프로퍼티의 이름을 반드시 큰따옴표(")로 감싸줘야 한다.
const member = {
  name: 'Michael Kim',
  height: 180,
  weight: 70,
  hobbies: ['Basketball', 'Listening to music']
};

자바스크립트에는 객체를 생성할 수 있는 여러 가지 방법이 있는데요. 그중 한 가지는 이런 식으로 중괄호('{ }') 안에 객체의 프로퍼티의 이름(키)과 값(밸류)쌍을 순서대로 나열해서 생성하는 방법입니다. 지금 보이는 표기를 Object Literal이라고 하는데요. Object Literal을 쓸 때는 문법에 약간의 유연함이 있습니다. 저는 지금 member 객체의 각 프로퍼티의 이름인 name, height, weight, hobbies에 큰따옴표를 붙이지 않았는데요. Object Literal에서는 이렇게 프로퍼티의 이름에 큰따옴표를 붙이지 않아도 되고,

const member = {
  "name": 'Michael Kim',
  "height": 180,
  "weight": 70,
  "hobbies": ['Basketball', 'Listening to music']
};

이렇게 큰따옴표를 붙여도 됩니다.

하지만 JSON의 경우에는 프로퍼티의 이름에 반드시 큰따옴표를 붙여줘야만 합니다.

{
   "name":"Michael Kim",
   "height":180,
   "weight":70,
   "hobbies":["Basketball", "Listening to music"]
}

지금 각 프로퍼티의 이름이 모두 큰따옴표로 둘러싸여 있죠? 이렇게 JSON에서는 각 프로퍼티의 이름을 반드시 큰따옴표로 감싸주어야 합니다. 큰따옴표로 감싸주지 않으면 JSON을 처리하려고 할 때 에러가 납니다.

  • JSON에서는 값이 문자열인 경우 큰따옴표(")를 사용해야 합니다.
const member = {
  "name": 'Michael Kim',
  "height": 180,
  "weight": 70,
  "hobbies": ['Basketball', 'Listening to music']
};

잠깐 member 객체를 다시 볼게요. 지금 name 프로퍼티의 값으로 'Michael Kim'이라는 문자열이 들어가 있죠? 자바스크립트에서는 문자열을 나타낼 때, 이렇게 작은따옴표(')를 써도 되고, 큰따옴표(")를 써서 "Michael Kim"이라고 써도 됩니다.

하지만 JSON에서는 문자열 값을

{
   "name":"Michael Kim",
   "height":180,
   "weight":70,
   "hobbies":["Basketball", "Listening to music"]
}

지금 보이는 "Michael Kim", "Basketball", "Listening to music"처럼 항상 큰따옴표로 감싸서 적어줘야만 합니다.

JSON에서는 표현할 수 없는 값들이 있습니다.

자바스크립트에서는 프로퍼티의 값으로 사용할 수 있는 undefined, NaN, Infinity 등을 JSON에서는 사용할 수 없습니다. 참고로, JSON은 비록 자바스크립트로부터 비롯된 데이터 포맷이지만, 그 탄생 목적은 언어나 환경에 종속되지 않고, 언제 어디서든 사용할 수 있는 데이터 포맷이 되는 것이었습니다. 따라서 자바스크립트의 문법에서만 유효한 개념을 JSON에서는 나타낼 수 없다는 것은 어찌 보면 당연한 결과입니다.

JSON에는 주석을 추가할 수 없습니다.

JSON은 코드가 아니라 데이터 포맷이기 때문에 그 안에 주석을 포함시킬 수 없습니다.
자, 이때까지 자바스크립트의 문법과 JSON 문법 간의 미세한 차이를 배워봤는데요. 이 둘은 일반적으로 호환되는 것이 맞지만, 위에서 살펴본 세부적인 차이가 있다는 점을 알아두는 게 좋습니다. 이런 차이가 있다는 것을 모르면, 나중에 실무에서 JSON 데이터를 처리하다가 에러가 생겨도, 그 이유를 이해할 수 없기 때문입니다.

JSON 데이터를 객체로 변환하기

fetch('https://jsonplaceholder.typicode.com/users ')
	.then((response) => response.text())
	.then((result) => { const users = JSON.parse(result); 
	 console.log(user.length);
	 user.forEach((user) => {
		console.log(user.name)
		)};
	});

GraphQL-API

클라이언트는 서버와 통신하는 애플리케이션이다. GraphQL의 장점은 유연함이기 때문에 클라이언트를 만들 때도 따라야할 규칙은없다. 또한 프로그래밍 언어나 만들고자 하는 앱의 종류도 자유롭게 선택 가능하다.

쿼리와 뮤테이션을 보낼 때 주의해야할 것은 HTTP 요청이 가능한지 여부이다. 요청에 대한 응답으로 서비스에서 데이터를보내면 어떤 클라이언트에서든 이것을 받아 사용할 수 있다.

GraphQL API 사용하기

클라이언트에서 GRaphQL을 사용하는 가장 쉬운 방법은 HTTP 요청을 엔드포인트에 보내는 것이다.

fetch 요청

터미널이나 커맨드 프롬프트에서 POST 메서드를 사용해 cURL 요청을 보내면 된다.
요청을 보내면 JSON 형식의 결과값을 받게 된다.

graphql-request

GraphQL API와 통신 가능한 프레임워크.
fetch 요청을 프로미스로 감싸, 이를 GraphQL 서버에 요청 보낼 때 사용한다. 데이터 요청 및 파싱 과정에서 필요한 세부 작업도 알아서 수행한다.

  1. 패키지 설치
npm install raphgl-request
  1. request 모듈을 불러와 사용
import { request } from 'graphql-request'

const query = `
	query listUsers {
    	allUsers {
        	name
            avatar
        }
    }
`

request('http://localhost:4000/graphql', query)
.then(console.log)
.catch(console.error)

URL과 query를 받아 서버에 요청을 보내고 데이터를 반환하는 함수 코드를 작성했다. 함수에서 반환하는 데이터는 모든 사용자가 들어 있는 JSON 응답이다.

  1. 뮤테이션 요청도 가능
import { request } from 'graphql-request'

const mutation = `
	mutation populate($count: Int!) {
    	addFakeUsers(count:$count) {
        	id
            name
        }
    }
`

const variables = { count: 3 }

request(url, mutation, variables)
.then(console.log)
.catch(console.error)

request 함수는 API URL, 뮤테이션, 변수 이렇게 세 가지 인자를 받는다.

아폴로 클라이언트

REST를 사용하면 캐시 다루기가 쉽다는 장점이 있다. 요청에 대한 응답 데이터를 캐시에 저장할 수 있는데, 요청을 보낼 때 사용한 URL 하위에 저장한다. 그러나 GraphQL 캐싱은 살짝 더 까다롭다. GraphQL API의 라우트가 여러 개가 아니라서 모든 요청이 하나의 엔드포인트로 전달되며, 응답도 하나로 전달된다. 따라서 요청 URL 라우트의 하위에 데이터 캐싱을 쉽게 할 수 없다.

성능 좋은 어플리케이션을 만들려면 쿼리와 객체 값을 캐싱해야 한다. 이를 위해 이미 어느 정도 품질이 검증된 클라이언트를 사용해도 된다.

현재 사용되는 GraphQL 클라이언트 중 가장 유명한 것은 Relay와 아폴로 클라이언트이다.

Relay는 React와 React Native만 지원하므로, React 외의 기술에서 사용할 GraphQL 클라이언트가 탄생할 여지가 있다. 그래서 아폴로 클라이언트가 나왔다. React, Angular, Ember, Vue, iOS, Android 등과 함께 사용할 수 있도록 패키지가 제공된다.

React와 아폴로 클라이언트

프로젝트 설정

  1. create-react-app 설치
npm install -g create-react-app
  1. React 프로젝트 생성
create-react-app photo-share-client

'photo-share-client'라는 폴더에 기본적인 React 애플리케이션을 생성해준다.
애플리케이션 실행은 'photo-share-application' 폴더로 들어가서 npm start 명령어로 한다.

아폴로 클라이언트 설정

아폴로 툴로 GraphQL 클라이언트를 만들려면 가장 먼저 GraphQL 언어 파서가 들어있는 graphql이 필요하다. 그리고 apollo-boost 패키지가 있어야 한다. 그 다음 react-apollo가 필요하다. 총 세 개의 패키지를 설치해준다.

ApolloClient 생성자는 apollo-boost에 들어있으며 이를 사용해 클라이언트를 만든다. 클라이언트를 만들어주고 나면 쿼리를 보낼 수 있고 로컬 메모리에 캐싱도 가능하다.

react-apollo를 사용하려면 우선 클라이언트를 만들고 Apollo Provider 컴포넌트와 함께 이를 사용자 인터페이스에 추가하면 된다.

VS CODE 에서 사용

axios

apollo-client

import { } from '@apollo/client'

const result = useMutation( API이름입력 )
const result = useQuery( API이름입력 )

Query 컴포넌트 (READ)

데이터를 받아 로딩 상태를 관리하고 UI를 업데이트 하는 일을 담당한다. (데이터 조회)

Mutation 컴포넌트 (CREATE-UPDATE-DELETE)

데이터를 생성, 수정, 삭제하는 일을 담당합니다.

profile
기술블로그 이전:: https://meercat.tistory.com/

0개의 댓글