오늘은 통신☎️ 에 대해서 배워보았습니다.
통신을 배우기 이전에 객체, 배열 타입의 복사💾 를 먼저 배워보았습니다. 객체와 배열 타입은 복사를 한 뒤, 데이터 값을 수정하게 된다면 복사된 데이터뿐 아니라 원본 데이터 값까지 같이 수정되는 것을 확인하였습니다. 이는 정확한 주소를 명시해 주지 않아서 발생하는 문제였습니다.
그래서 우리는 위의 문제를 해결하기 위해 스프레드 연산자를 활용해 얕은 복사를 실습해 보았습니다. 엄밀히 말하면 복사가 아니라 스프레드 연산자를 사용하여 새로운 객체를 만들어준 것이었죠? 하지만 이 또한 완벽한 복사는 아니었습니다. 객체 안에 객체가 존재할 때, 안에 존재하는 객체의 값을 수정하게 된다면 원본과 복사된 데이터의 값 모두 수정되는 문제가 다시 발생하였습니다.
때문에 모든 데이터를 완벽하게 복사할 수 있는 깊은 복사의 필요성을 알게 되었습니다. 깊은 복사를 위해 우리는 JSON.stringify()를 통해 객체 전체를 문자열로 바꿔준 뒤, JSON.parse()로 해당 문자열을 새로운 객체로 다시 변환시켜 주는 과정을 거쳤습니다.
또한, REST 파라미터 를 사용해서 내가 필요한 데이터만을 가진 사본을 만들면서 조금 더 안전한 코드로 사용하는 방법도 알아보았습니다.
그리고 API 통신 에 대해 배웠습니다. 웹 서비스에서의 통신이란 데이터 요청과 응답을 의미하였습니다. 데이터의 생성/조회/수정/삭제 등을 요청했을 때 각각의 요청마다 담당하는 담당자를 API라고 불렀는데 데이터의 처리를 요청하는 하나의 기능, 함수라고 생각하시면 쉽습니다.
API의 종류에는 크게 rest-API, graphql-API 두가지가 있었죠?
rest-API 는 홈페이지 주소처럼 생겼었고, axios로 데이터를 요청하여 응답 결과로 모든 데이터를 받아왔습니다. 반면 graphql-API 는 일반 함수와 같이 생겼으며 apollo-client로 데이터를 요청하여 필요한 데이터만 골라서 받을 수 있었습니다.
API는 크게 생성/수정/삭제/조회 4가지 방식으로 구분하고 이것을 CRUD라고 부른다고 했습니다.
rest-API는 CRUD 각각의 명령어가 POST/GET/PUT/DELETE로 모두 달랐지만, graphql-API READ는 Query, 나머지는 Mutation 명령어로 더 간단하게 데이터 통신을 요청할 수 있었습니다.
이렇게 CRUD를 하기 위한 API가 어떤 것이 있고, 어떻게 구성되어 있는지 확인할 수 있는 문서를 rest-API는 swagger에서 확인하여 postman에서 연습해 볼 수 있고, graphql-API는 playground에서 문서의 확인과 연습을 둘 다 해볼 수 있었습니다. 때문에 grqphql을 사용하시면 더 효율적이고 편리하게 데이터 통신을 하실 수 있겠습니다. rest-API와 graphql-API의 차이점, 이해하시겠죠?
어떤 API를 사용하든, javascript로 데이터를 요청하고 응답을 받았을 경우 객체처럼 표기되어 응답을 받았었습니다. 우리는 이것을 JSON(JavaScript Object Notation) 이라고 부릅니다.
데이터를 어떻게 요청하고 어떻게 받아오는지의 과정을 잘 이해하고 있어야지 API를 만들고 만든 API를 test 해 볼 수있기에 playground에서 많이 연습해 보시면서 이해도를 높이시길 바랍니다.
복사는 원본과 복사본으로 나뉜다!
코딩에선 거의 원본을 직접 수정하지 않는다!
그래서 복사를 해서 저장한다!!!
문자열의 복사
위에는 문자열 복사를 시도해본 예시이다.
콘솔에서 위와 같이 문자열의 복사를 직접 시도해 볼 수 있다!!
객체의 복사
하지만 객체의 복사는 조금 다르다!
객체는 위에 문자열이나 숫자를 복사하는 것과 달리 여러 값이 가지고 있기 때문에, 복사를 할 때 값이 복사되지않는다!!!
값이 복사된다고 생각했겠지만 사실은 그 값이 있는 주소가 복사된 것이였다!!!!!!!!
그래서 문자열을 복사하듯이 객체를 복사하면 밑에 코드처럼 profile의 값이 변경될 때, 똑같은 주소를 사용하는 profile2도 값이 같이 바뀐다!!!📌 참고
const profile = {여기 중괄호 부터 주소}
이와 같은 문제를 해결하기 위해 사용된 것이 바로 얕은 복사와 깊은 복사다!!!
위에서 얘기했던 것처럼 원본에 영향을 주지않는 완전히 새로운 복사본을 만들기 위해서 얕은 복사를 사용할 수 있다!
사진에서 작성한 코드처럼 완전히 새로운 객체(새로운 주소{})를 생성해주고 기존의 객체의 주소가 아닌, 실제 값을 복사해서 넣어줬다!
이렇게 만들면 profile2의 내용을 바꿔도, 원본인 profile의 내용은 바뀌지 않는다!!!(서로 영향을 주지 않는다.)그렇지만 위처럼 하나하나 nama: profile.name 이런식으로 값을 가져오는 것은 너무 번거로웠다.
그걸 해결하는 것이 바로 스프레드 연산자!!!스프레드란 흩뿌려준다는 뜻인데 뜻 그대로 원본객체의 값들을 완전히 새로운 복사본에 흩뿌려주는 역할을 한다!
사용방법
위 사진과 같이 괄호 안에서 ...을 객체나 배열 앞에 작성해서 사용할 수 있다!!
그런데 이 코드를 보면 또 문제가 보인다.
객체를 분명 복사했는데 객체 안에 있던 객체인 hobby가 복사본인 newProfile2를 고쳤더니, newProfile도 값이 바뀌었다!!!📌 왜 그러는 걸까?
스프레드 연산자는 말 그대로 얕은 복사이기 때문이다!!!!
얕은 복사이기 때문에 객체 안에 객체까지는 복사를 못하고 원본 hobby의 주소값만 복사 된 거였다!!!
얕은 복사로만 객체 안에 있는 객체까지 복사하려면 어떡해야할까?
생각보다 간단했다!!!스프레드 연산자로 불러운 값 밑에 hobby 값을 또 스프레드 해준다!!!!
그러면 newProfile3를 수정해도 newProfile은 바뀐게 없다!!!!하지만 생각해보면 이것도 너무 번거롭당
또 이 번거로움을 해결하기 위해서 쓰는 것이 깊은 복사다!!!!!
deep copy, 혹은 깊은 복사라고 하는 것은 직접 코드를 작성해서 값을 복사해온 불편함을 해결해주고 간단하게 객체의 완전한 복사를 하게 해준다.
JSON.stringify
: 인자로 들어온 데이터를 문자열로 변환해주어서 객체 모양을 한(객체의 주소가 사라진: 왜?객체가 아니라 문자열로 바꼈으니까!)문자열을 돌려준다.
우리는 데이터를 주고 받는 도구로 여러가지를 사용한다. 우리는 그 중 HTTP 통신을 하는데,
밑에서 더 자세히 쓰겠지만 HTTP는 텍스트로 데이터를 주고 받습니다.
그래서 깊은 복사를 하기 위해 객체 데이터를 전송할 때는 JSON.stringify 를 통해 객체를 문자열로 바꿔서 보내준다고 했다!!JSON.parse
: JSON.stringify를 통해 받은 문자열을 다시 객체 형태로 변환시켜준다.
JSON.stringify를 문자열을 받았으면 그 문자열을 사용하기 위해 다시 객체형태로 우리는 변환을 시켜줬어야했다!
그렇게 만들어주는게 바로 JSON.parse 였다!!그래서 최종적으로 정리해보자면 어떠한 객체를 완전히 새로운 객체로 선언할 때 깊은 복사를 사용한다면 JSON.parse(JSON.stringify)를 사용해주면 원본 객체가 문자열로 변환되어 데이터를 전송해주고, 그 받은 문자열 데이터를 다시 객체로 변환시켜 아예 새로운 객체를 만들 수 있었다!!!
깊은 복사의 단점
깊은 복사는 많은 것을 복사해야 하기 때문에, 속도가 느리다는 단점이 있다!!
그래서 이걸 개선하기 위해서 사용되는 것이 lodash다!
lodash는 라이브러리인데 npm사이트에서 설치방법과 사용방법 등을 알 수 있었다!
위에 여러가지 상황들을 콘솔에 찍어서 확인해 봤는데 나는 이때 궁금해질 수 밖에 없었다!
왜?
const는 재할당을 할 수 없는 앤데 나는 계속 객체 값을 새로운 값으로 변경할 수 있었던 이유는 계속 얘기했던 것처럼 주소가 들어가 있었기 때문이다!!!
이렇게 객체를 선언했을 때 const로 잡혀서 재할당을 못받는 것은 profile이다.
하지만 profile 안에 있는 키와 값들은 const로 묶여 있지않다!!
그렇기 때문에 값을 다시 줄 수 있었던 것이다!!!!정리하자면 profile은 const로 선언되었기때문에 값을 재할당 할 수 없지만,
profile.name 이나 profile.age 등 그 안에 들어있는 객체는 const가 영향을 끼치지 못했기 때문에 재할당이 가능하다!!!
만약 객체까지 const처럼 고정시키고 싶다면 object.freeze(profile)하면 위처럼 새로운 값을 주어도 기존 값이 나온다!!!!
지금까진 객체에서 특정 키를 지우고 싶을 땐 delete 메소드를 통해 사용했었다.
하지만 만약 그게 공통으로 사용하는 컴포넌트 파일이나 자주 사용하는 library 파일 값이라면 다른 곳에서는 그 키 값을 사용할 수도 있었다!!
그렇기 때문에 원본 객체를 직접 수정하는건 실무에서는 옳지않다!!!!
이럴 때 구조분해할당을 활용한다!!
위 사진과 같이 child라는 객체가 있을 때, school을 제외한 값을 사용하고 싶다면const {school, ...rest} = child
앞에는 지우고 싶은 키를 쓰고 ,를 써서 나머지 키들은 스프레드 연산자를 활용해서 묶어준다!
이때 rest는 변수명이여서 각자 자기가 쓰고 싶은 명칭을 쓰면 된다!!!
그리고 콘솔을 찍으면 school을 제외한 객체들이 들어가있는 값이 rest라는 변수에 새롭게 저장된다!!!
: HyperText Transfer Protocol의 약자로 두 컴퓨터간에 텍스트 데이터를 주고 받는 길이다!
데이터를 주고 받을 수 있는 도구들은 여러가지가 있는데, 그것들은 데이터의 종류에 따라 방법이 달라진다.
그 중 HTTP는 텍스트 데이터를 주고 받는다!
통신은 무조건 요청(request or req)과 응답(response or res)이 있어야한다!!!!!!!!!!
응답을 해줄 땐 프론트엔드에게 상태코드를 함께 넣어서 보내주는게 일반적이다.⛔️ 상태코드
200번대 : 성공
400번대 : Front-end 에러(클라이언트 오류)
500번대 : Back-end 에러(서버 오류)
이 외에도 많은 상태코드들이 있으니 한번 구글에서 상태코드를 검색해보쟈!!!
: HTTP 요청을 Back-end 컴퓨터에 보냈을 때 실행되는 Back-end 기능
우리는 화면에서 수많은 버튼을 볼 수 있다. 벨로그 글을 작성할 때만 봐도 나가기 버튼, 임시저장 버튼, 출간하기 버튼 등 많은 버튼이 있다.
이런 버튼이 많다는건 그에 대한 API도 많다는 거다!
즉 Front-end에서 화면을 구상하는데 필요한 여러 데이터들을 요청할 때, 각각 그 요청에 맞는 응답을 주어야하는데 그걸 api라고 한다!!!✅ API는 함수이다!!!
우리가 기능이라고 배운 api는 사실은 백엔드 개발자가 만든 함수였다!
함수는 인자와 return 데이터로 이루어져 있는데, api에 요청할 때 보내는 데이터는 api 함수로 들어갈 인자 이고, 응답으로 받게되는 데이터가 api 함수의 return 데이터였다!!API의 종류
api는 Rest-api와 Graphql-api이 있다.
Rest-API
역사가 깊고 많이 사용하고 있는 api이다.Graphql-API
rest-api의 느린 속도를 개선할 수 없을까 고민하던 페이스북이 새로 만든 api
대규모의 트래픽에서 효율적이다. 이후 에어비앤비, 넷플릭스 등이 graphql을 사용한다.하지만 Rest와 graphql 둘 다 할 수 있어야 한다!
📌 왜 그러는 걸까?내가 취업한 회사가 rest-api 를 사용할지 graphql-api를 사용할지 알 수 없다!
아직 국내에서는 큰 서비스가 아니거나 기술에 민감한 스타트업이 아닌 이상 rest-api가 더 많다!
다른 개발자들이 무료로 공유해준 무료공개 api(=public api)가 거의 rest-api다.
Rest-api와 Graphql-api의 차이
rest는 front-end에서 1번 게시물을 요청 할 때 back-end가 db에서 게시물 값을 응답해주는데,
내가 요청한 1번 게시물 안에 있는 모든 데이터를 받아야했었다!!
이게 왜 문제인지를 예시로 알 수 있다. 게시물 목록창을 만들 때, 게시물의 제목만 가져와서 리스트를 보여주면 되는데 굳이 모든 데이터를 받아야한다면 그 용량도 크고 데이터를 통신할 때 드는 비용이 너무 많이 들었다! 이걸 개선하기 위해서 나온 것이 페이스북이 만든 graphql이다!
graphql은 front-end가 1번 게시물의 제목만 요청이 오면, back-end가 db에서 1번 게시물의 제목만 뽑아서 응답해준다!
- 그래서 각 API에 전송을 요청하는 담당자(front-end에서 설치하는 라이브러리)도 다르다
Rest-API => axios, Graphql-API => apollo-client
: 자바스크립트(Javascript)의 객체(Object)처럼 표기(Notation)한다고 해서 자바스크립트 객체표기법이라고 한다.
HTTP는 텍스트 데이터를 주고 받는거기 때문에, 객체로 주고 받을 수 없다.
그래서 객체를 text로 바꿔서 주고받은 뒤에 받은 text를 객체로 변환해서 사용한다.
어떤 기능 1개를 만든다 할 때, 최소 5개의 API가 필요하다!!!
C(생성) + R(조회) + U(수정) + D(삭제) + 목록CRUD는 api 종류에 따라 다르게 사용된다.
Rest-API
는 CRUD 마다 사용하는 방식(method)이 존재하고,
GraphQL-API
는 데이터를 조작하지 않고 조회만 할때는 QUERY, 그 외의 데이터를 조작할 때는 MUTATION을 사용한다!한장에 정리
와 징쨔 수업 때 안졸고 이해하려고 다 적어뒀던거 다시 보면서 블로그를 쓰는데 양이 확 후덜덜이다,,
블로그 정리로만 밤을 샜다,,,그래도 이 시간 덕분에 프론트 공부하면서 잘 이해가 안됐던 깊은 복사와 스프레드 연산자, HTTP 통신, API를 제대로 이해할 수 있던 것 같다!!!!
그리고 프론트 때는 graphql을 주로 사용해서 rest-api를 실습하지 못한게 많았는데, 이번에 포스트맨과 스웨거의 사용법을 익힐 수 있었다!
까먹지 않게 graphql을 배우면서도 rest 연습을 소홀히 하면 안되겠다 생각함,,,
이제 4일차부터 직접 api를 만들어보기 시작한다,,걱정도 되면서 실제로 내가 만든 api가 보이니까 두근두근해,,,
졸지말고 열심히 하쟈아앙