Graphql / Apollo

이병관·2021년 5월 13일
0
post-custom-banner

Graphql



보내진 데이터


게시물

app.js

import {ApolloClient,InMemoryCache,ApolloProvider} from '@apollo/client';

Apollo를 Import 후 필요한 모듈을 가져온다.

import {ApolloClient,InMemoryCache,ApolloProvider} from '@apollo/client'

function MyApp({ Component, pageProps }) {
  const client = new ApolloClient({
    uri:"http://example.codebootcamp.co.kr/graphql",
    cache: new InMemoryCache()
  })
  

apolloclient객체를 생성하기 위해 서버의 접속 정보가 반드시 필요하다.
따라서 테스트 할때 만일 테스트용 서버가 없다면 Mockprivider를 통해 가짜 데이터를 전송시켜볼수 있다

https://www.apollographql.com/docs/react/development-testing/testing/
MockedProvider는 ApolloClient 객체를 필요로 하는 ApolloProvider와 달리 단지 가짜 데이터만을 필요로 한다.

이제 연결 작업은 마쳤으니 기능을 추가해주자

Write.js


import{useMutation, gql} from "@apollo/client";

client모듈을 일단 import시키자. 그리고 Query문을 날리는게 아니라 Post를 할 예정이니 Mutation을 가져오자.


정신이 아득해졌다

일단 추가한 부분들은 React-hook의 Form기능을 사용하기 위해

{...register("RequiredValue", { required: true })}

을 삽입해서 만일 해당 값이 비었는데도 Submit을 누를경우 행위를 멈추고 해당 Input에 Focus를 주기위해

import {useForm} from 'react-hook-form';
const{handleSubmit, register} = useForm();

을 가져오고 선언하였다. 그리고 입력받는 모든 부분을 Form으로 감쌋다.

이것에 대한 공부는 좀 많이 필요할것같다. 매우 유용하지만 아직 공부와 수행이 부족해 외계어처럼 느껴진다.

자자 각설하고 다시 원래 부분으로 돌아가자

<Writer id='writer' type="text" placeholder="이름을 적어주세요." {...register("nameRequire", { required: true })} 
onChange = {handleOnChange}/>

동적으로 입력받은 값들을 가져오기 위해 onChage 메소드를 넣었다. 이친구가 이제 값이 변할때마다 원하는대로 조작할수 있게 도와줄것이다...

markdown logo

함수 onChange

그럼 저 친구의 변화를 바라보는 함수는 어떤 함수일까?

const[inputs, setInputs] = useState({
    writer:'',
    password: '',
    title: '',
    contents: '',
  })


  const handleOnChange = (e) =>{
    setInputs({
      ...inputs,
      [e.target.id] : e.target.value
    })
    console.log(e.target.value);
  }


뭐든 차근차근하면 이해하기 쉽다

자자 일단
const[inputs, setInputs]
를 통해 usestate를 선언 해 준 뒤, input의 갯수가 너무 많으니 따로따로 하나씩 만드는거보다 객체에 모조리 담아 보낼때만 쇽쇽 해당하는 값에 보내면 편할것이다.
따라서 객체로 key값을 해당 input의 id로 할당하고, 그것의 값으로 value를 설정한다면? 끝이다.

다만 새로운 input을 만날시, 이전 input이 초기화 될 수 있기에 Spread문법으로
...inputs, [e.target.id] : e.target.value })
이전 arg친구들을 모조리 데려와 복사시킨다면 이것 역시 가볍게 클리어 해버릴수있다.

함수 onClick

import{useMutation, gql} from "@apollo/client";
...

const postContentGql = gql`
 mutation($writer: String, $password: String, $title: String, $contents: String){
   createBoard(
   writer:$writer,
   password:$password,
   title:$title,
   contents:$contents
   ){
     message
   }
 }
 `;
...
const [postRequest] = useMutation(postContentGql)
....


async function hadleClickOnPost(){
     const result = await postRequest({
       variables:{...inputs}
     });
     console.log('This is Mutation Function');
     alert(result.data.createBoard.message);
 }

핵심만 집고 넘어가자 핵심만

일단 우리는 값을 새로 만들예정이니 useMutation을 가져와야한다. 그리고 그것을 graphql이 먹을수 있는 형태로 만들어 주기 위해 gql모듈을 가져온다.

자! 원하는 모듈을 가져왔으니 이제 그것을 어떻게 보내줄지 선언을 해야한다.

postRequest라는 이름을 가진 놈으로 우리는 Mutation시켜주고 싶은데 그 Mutation을 시킬 내용은 바로 postContentGql의 내용이야! 라는 놈을

const [postRequest] = useMutation(postContentGql)

라고 이쁘게 적어준다.

자 그러면 이제 게시물에 어떤 내용들이 들어가는지 알려줄 차례다.
게시물이기에 당연히! 비동기로 처리를 해줘야한다.
그게 아니면 수천개의 요청들이 다른 요청들이 끝날때까지 손가락을 빨고 있어야하니깐.

그러면
async로 나는 이친구를 비동기화로 만들꺼고 그거에 해당하는 함수는 await야 라고 async & await를 걸어줘야한다.

async function 함수명() {
await 비동기 처리 메서드명();
}
일반적으로 await의 대상이 되는 비동기 처리 코드는 Axios나 Apollo 등 프로미스를 반환하는 API 호출 함수다.

그렇다면 이야기가 이제 쉬워진다.
result란 변수 안에 위에서 선언한 postRequrst를 넣어주고 그것 안에 들어있는 내용은 위에서 적어준 ...input 친구들이다. 이미 키값과 넣어주고 싶은 곳의 키값이 똑같기 때문에 따로
writer = input.user와 같이 선언을 하지 않아도 된다. 그냥 Spread로 똑디 가져오면 된다.

자. 이제 이야기는 끝났다. 전송버튼에 onClick이벤트를 부여하고 제발 오류가 없길 기도하며 쏴주자

markdown logo

잠시만 안에 친구가 객체잖아

오류가 발생했다. CreateBoard에서 받는게 아니라 안의 Arg에 담아주는것이였다.
내 기도가 또다시 이율배반적 상황에 놓였지만 다시 차근차근 살펴보자

일단 출력하는 Return값이 없다. 따라서 message부분은 오히려 오류를 발생시킬것이다.

const postContentGql = gql`
  mutation($writer: String, $password: String, $title: String, $contents: String){
    createBoard(
    writer:$writer,
    password:$password,
    title:$title,
    contents:$contents
    ){
      message
    }
  }
  `;

일단 반환하는 return값이 없기 떄문에 message부분을 없애주고,
객체형으로 담아주어야하니 createBoard에 CreateBoardInfo의 객체에 해당 값들을 담아주면 될것이다.

const postContentGql = gql`
  mutation ($writer: String, $password: String, $title: String!, $contents: String!){
    createBoard(createBoardInput: {
      writer:$writer
      password:$password
      title:$title
      contents:$contents
    })
    {
     writer,contents 
    }
  }
  `;

이젠 오류가 없다! 다행이다...


하이라이트

  1. 해당 input의 이름이나 아이디가 이상하지 않게 반드시 숙지하자. 그거때문에 몇번이고 실패해서 다른곳에서 오류가 있나 삽질했다.

  2. Axios와 다르게 Apollo는 조금 설정해야할것들이 있는데 그것에 대한 공부도 필요하다

  3. onChange를 할때 객체를 사용하여 하나의 이벤트 핸들러로 조정할수 있도록 다시금 숙지하자. 원래 코딩이라는게 돌아서면 종종 까먹곤 하지않는가?

profile
뜨겁고 매콤하고 화끈하게
post-custom-banner

0개의 댓글