GraphQL API 만들기 -2

hodu·2023년 2월 21일
0

앞에서는 공부할 때 One, two, three로 만들었는데,
sementic하지 못해서 관계성을 생각하기 어려웠다.
그래서 재작성하여 graph ql SDL을 수정했다.

const typeDefs = gql`
  type user {
    id: ID
    userName: String
  }

  type Tweet {
    id: ID
    text: String
    number: Int
    checked: Boolean
    author: user
  }

  type Query {
    allTweets: [Tweet]
    tweet(id: ID): Tweet
  }
`;

이어서 POST/API/v1/tweets를 한다고 생각해보자.
이럴 경우에는 type Mutation을 선언해야한다.
Mutation의 역할은 user 보낸 data들로 mutate하는 동작을 모두 넣어준다.

type Mutation {
	postTweet(text: String, userId: ID): Tweet
}

user가 data를 보내고 backend를 mutate 한다면 그건 mutation이다

type Query = GET Method
type Mutation = POST method


Root Types을 보면 query와 mutation 2개가 된 것을 볼 수 있다.
같은 타입인 user와 Tweet은 생기지 않았다.

  type user {
    id: ID
    userName: String
  }

  type Tweet {
    id: ID
    text: String
    number: Int
    checked: Boolean
    author: user
  }

그리고 Operation을 보면 mutation이라고 적었다
이는 default 값이 Query라서 다른 경우에는 꼭 써줘야한다.


이렇게 작성할 수 있다.

DELETE, PUT 같은 Method를 작성할 수 있는데 POST와 마찬가지로
이 모든 것을 mutation 안에서 해결한다.
왜냐하면 이 3가지 모두 database를 mutate하는 것이다.

type Mutation {
	deleteTweet(id: ID): Boolean
}

delete가 끝나면 Boolean 값을 리턴한다.
(타입은 대문자로 작성해야한다.)


  type Tweet {
    id: ID!
    text: String!
    number: Int
    checked: Boolean
    author: user | null
  }

! 작성할 경우에 이 부분은 필수가 된다.
그리고 graphql에서 타입은 기본적으로 or null이 붙어 있다.
영어로는 nullable field라고 한다.
author 처럼 null 을 넣어줘도 오류가 뜨지 않는다.
이것은 argument도 마찬가지이다.
argument에 ! 가 없다면, 작성하지도 않아도 graphql은 자연스럽게 돌아간다.
null을 허용하기 때문이다.

  type Query {
    allTweets: [Tweet]
    tweet(id: ID!): Tweet!
  }

리턴값을 필수로 만들 수 있지만, Tweet! 문장은 잘못되었다.
존재하는 id값이 아니라면 리턴해줄 값이 없기 때문에 !를 작성해서는 안된다.

배열해서 !를 사용한다면, [Tweet]! 경우에는 무조건적으로 배열을 리턴할 것이고
[Tweet, null, Tweet] 이런식으로 올 수 있다.
[Tweet!]! 이 양식으로 작성한다면 배열안에 null이 아닌 오직 Tweet만이 올 수 있다.

아까처럼 아폴로에서 allTweet을 불러준다면, null을 리턴하기때문에 오류가 뜬다.

Resolvers

어떤 언어를 쓰냐에 따라 달라진다.

const resolvers = {
	Query: {
    	tweet(){
        console.log("i,m");
        return null;
        }
    }
    
}

여기서 네이밍은 중요하다 이름이 같아야지 작동한다

Apollo가 누군가의 query의 tweet을 요청한다면,
resolver의 tweet의 query로 가서 function을 실행한다.

먼저 Apollo에서 실행하면


콘솔값이 잘 찍히는 것을 볼 수 있다.

  type Query {
    allTweets: [Tweet]!
    tweet(id: ID): Tweet
    ping: String!
  }


작성하면 전과 같이 null이 나와서 오류가 뜬다.


const resolvers = {
  Query: {
    tweet() {
      console.log("안녕");
      return null;
    },
    ping() {
      return "pong";
    },
  },
};


결과 값이 잘나오는 것을 볼 수 있다.

더미데이터를 이용해서 모든 트윗을 내보내는 allTweet을 만들 것이다.

const resolvers = {
  Query: {  
    allTweets() {
      return tweets;
    },
  },
};

쓰면 결과 값으로 tweets(더미데이터) 내보낼 것이다.

이번에는 argument 값을 받아서 출력해보자

    tweet(root, args) {
      console.log(args);
      return null;
    },

잘 받아오는 것을 확인할 수 있다.
우리가 argument를 보내서 query를 보내면 무조건 2번째에 argument가 들어온다.
이것은 서버에서 약속이고, 첫번째는 무조건 root이다.

    tweet(root, {id}) {
   
      return tweets.find((tweet)=> tweet.id === id);
    },

위 결과값을 이용해 id를 이용해 더미에서 데이터를 찾아주고 결과값을 받을 수 있다.

resolver에서 중요한것은 query 와 네이밍이 같아야한다.

profile
잘부탁드립니다.

0개의 댓글