GRAPHQL API 시작 (1)

suliver·2024년 6월 26일

GRAPHQL

목록 보기
4/5
post-thumbnail

1. 서버 시작

  • 터미널에 http://localhost:4000/ 클릭한다.
  • Query your server 버튼을 누른다.
  • Query는 text랑 hello를 가지고 있는 것을 볼 수 있다. (server.js에 작성 했기 때문이다.)
  • 아래 코드 입력하고 실행
{
  text
  hello
}

  • server.js에 작성한 것처럼 String이 return해야되는데 null 값이 나왔다. (1. 왜 에러가 안 뜰까?, 2. 왜 null이고 누가 null이라고 하는걸까? 그리고 이걸 어떻게 바꿀 수 있을까?)

2. null 값이 나온 이유

  • 우리 API가 생긴 모양을 graphql에 설명해 주어야 한다.. 그러고 나서 사용자가 원하는 data를 만들어낼 수 있도록 실제 코드를 작성해야 한다.

  • type Query 안에 있는 코드를 지우고 아래 코드로 변경한다.

	allTweets:

  • allTweets을 요청 받으면 database에 있는 모든 Tweet을 유저한테 전달하고 싶기 때문에 Scalar type을 쓸 수가 없다.

    Scalar type이란?

    • graphql에 built-in되어 있는 것이다.
    • 예를 들면, String이라는 type, Int라는 type, Boolean이라는 type, ID라는 type을 가지고 있다.

3. 새로운 타입 만들기

  • allTweets에 Scalar type을 쓸 수 없으니까 새로운 타입을 만들어 줄 거다.
  • Tweet은 ID type의 id하고, String type의 text를 가질 것이다.
  • 아래 코드 입력
type Tweet {
	id: ID
	text: String
}

  • allTweets field가 Tweet의 list type을 리턴할 수 있도록 아래 코드 입력해준다.
allTweets: [Tweet]

4. Studio 확인

  • Studio는 우리가 Query 안에서 allTweets라는 field를 request할 수 있다는 것을 알 수 있다.

  • allTweets는 Tweet의 list를 준다

  • request를 해보자.

  • Operation에 아래 코드 입력 후 실행

allTweets {
	id
	text
}

  • 여전히 null이라고 하지만 곧 바꾸어 볼거다.

5. User type 만들기

  • User type을 만들어 줄거고, User는 ID type의 id하고, String type의 username을 가질 것이다.
  • 아래 코드 server.js에 입력
type User {
	id: ID
	username: String
}

  • Tweet type이 user에 의해 만들어졌다고 해 볼 것이다.
  • creator나 author라고 하고 type은 User가 될 것이다.
  • Tweet type에 아래 코드 추가
author: User

  • 이것처럼 Tweet의 list로 [Tweet]을 쓰는 것과 그냥 User 하나를 쓰는 건 엄청나게 다른 것이다.

  • 둘 다 database에서의 관계에 따라 결정된다.

  • Tweet type이 하나의 author를 갖는다는 말이고 allTweets type는 여러개의 Tweet을 준다는 것이다.

6. 하나의 Tweet 만들기

  • 모든 Tweet들을 받아오는 거 대신에 하나의 Tweet만 받아오려고 한다.
  • 아래 코드 입력
tweet: Tweet

  • 문제는 user가 말하는 Tweet이 어떤 건지 모른다는 것이다. 그래서 하나의 tweet을 request하는 사람은 Tweet의 id를 말해줄 것이다.
  • 아래 코드 입력
tweet(id:ID): Tweet

  • 이제 이 request를 받는데, tweet의 id를 함께 받을 것이다. 그러니 그저 그 tweet을 찾으면 된다.

    Type Query에 대해

    • Type Query은 실행 코드가 아니라 type에 대한 설명이다. 그러니까 어떤 field가 return될 지에 대한 설명이다.
    • graphql에서 query는 rest API에서 GET request를 만드는 것과 같다.
    • rest API에서는 URL variable이 있다면 graphql에서는 argument가 있다
  • 다시 Studio로 돌아오면 Arguments라는게 있다.

  • 만약 하나의 tweet을 받고 싶으면 $tweetId에 1, 2, 3, 4, 5와 같이 tweet의 id가 뭔지 알려줘야 한다.

7. Mutation type 만들기

  • Mutation type에 POST request 같은 모든 것들을 넣어 줄 것이다.

  • user가 보낸 data로 mutate하는 동작들을 모두 넣는 것이다. 예를 들어 database가 있다.

  • user가 tweet을 post하려면, tweet의 내용을 줘야한다. 그러니까 user는 String 하나를 보내야 한다. 그리고 이 Mutation이 끝나면 user한테 새로운 tweet을 줄 것이다.

  • 일단 지금은 authentication이 없기 때문에 user한테 userId를 받아와서 tweet을 만들거다.

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

  • 만약 user가 그냥 data를 받게 하고 싶은거라면 그건 Query type 안에 있어야하고, user가 data를 보내고 그게 backend를 mutate 한다면 그건 Mutation type 안에 있어야 한다.

  • Mutation type에 field를 추가하는 건 url를 노출시키고 POST HTTP method로 그걸 관리 하는 것과 같다.

  • deteteTweet은 id가 필요가 필요하다.

  • id를 받지만 Tweet을 return하진 않을거다. 왜냐하면 그 Tweet을 삭제됐을 테니까 그래서 Boolean을 return 해줄 것이다. 그래서 tweet을 삭제하려고 할 때 그 tweet을 찾았다면 true, 못 찾았다면 false를 return 할 것이다.

deleteTweet(id: ID): Boolean

8. Non Nullable Fields

  • 예를 들어 이 tweet(id: ID): Tweet코드에서 Tweet type은 graphql에게는 이게 Tweet이 될 수도 있고 null도 될 수 있는 것이다.

  • tweet(id: ID): Tweet코드에서 tweet(id: ID): Boolean 이런 식으로 Tweet 대신에 Boolean이라고 쓴다면 graphql은 이걸 보고 이 query는 Boolean이나 null을 준다고 생각한다. 이게 기본 값이고 null이 될 수 있는 field라서 Nullable Field라고 한다.

  • 만약에 필수로 만들고 싶으면 "!"를 붙여주면 된다. 예를 들어 tweet(id: ID): Tweet코드에서 id를 필수로 만들고 싶으면 tweet(id: ID!): Tweet 이렇게 써주면 된다. 이제 tweet Query를 쓰고 싶으면 ID를 꼭 전달해야 한다. 만약 전달 안 할 경우 에러가 발생한다.

  • 이제 코드에 !를 추가해 줄 것이고 User type에 firstName, lastName도 추가 해 줄 것이다.

const typeDefs = gql`
    type User {
        id: ID!
        username: String!
        firstName: String!
        lastName: String!
    }
    type Tweet {
        id: ID!
        text: String!
        author: User!
    }
    type Query {
        allTweets: [Tweet!]!
        tweet(id: ID!): Tweet
    }
    type Mutation {
        postTweet(text: String!, userId: ID!): Tweet!
        deleteTweet(id: ID!): Boolean!
    }
`;

0개의 댓글