[TIL] GraphQL API 만들기

한재창·2023년 5월 7일
0

GraphQL API

GraphQL을 왜 사용해야 하는가?

  • 필요한 데이터만 가져와서 쓸 수 있다.
  • 여러번 서버 통신을 해야 하는 상황에서 한 번만 할 수 있게 해준다.

GraphQL의 사용 방법

  • setup
    • 터미널에서 npm install apollo-server graphql 입력 후 설치해준다.
    • package.json 파일에서 "type": "module" 선언해준다.
    • server.js 파일을 만들어준다.
    • server는 new ApolloServer 생성자로 지정해주고, typeDefs 가 반드시 필요하다.
    • typeDefs는 gql함수를 호출하며 백틱안에 type들을 생성해준다. Query 타입은 필수로 생성해야 한다.
import { ApolloServer, gql } from "apollo-server";

const typeDefs = gql`
	type Query {}
`;

const server = new ApolloServer({
  typeDefs,
});

server.listen().then(({ url }) => {
  console.log(`Running on ${url}`);
});
  • GraphQL Schema 정의
    • 위에서 말했듯이 type Query는 필수로 생성하고, 사용자가 request 하고 싶은 것은 Query 안에 있어야 한다.
    • 모든 field는 기본적으로 nullable 이다.
      • 따라서 id: ID === id: ID|null 이다.
      • id: ID! 처럼 뒤에 !를 붙이면 required id: ID !== id: ID|null 이다.
    • 사용하면서 느낀건데 typeScript의 사용방법이랑 비슷하다.
      • type Tweet를 정의하고 그 타입을 Query에서 사용한다.
      • firstName: String 처럼 firstName 은 문자열의 값밖에 가지지 못한다.
    • backend를 mutate하는 것들은 type Mutation 안에 넣어줘야 한다.
      • POST, DELETE, PUT이 여기에 해당된다.
const typeDefs = gql`
  type User {
    id: ID!
    firstName: String!
    lastName: String
    # Document 에 설명을 남겨준다.
    """
    Is the Some firstName and lastName as a String!
    """
    fullName: String!
  }
  type Tweet {
    id: ID!
    text: String!
    author: User
  }
  type Query {
    allUsers: [User!]!
    # allTweets 라는 field
    allTweets: [Tweet!]!
    tweet(id: ID!): Tweet
  }
  type Mutation {
    postTweet(text: String!, userId: ID!): Tweet!
    deleteTweet(id: ID!): Boolean!
  }
`;
  • REST vs GraphQL
// REST 방식
 GET /tweets; type Query
 POST DELETE PUT /tweets; type Mutation
 GET /tweet/:id;

// GraphQL 방식
const typeDefs = gql`
	type Tweet {
    	id: ID!
    	text: String!
    	author: User
  	}
	# Get
	type Query {
   	 	allTweets: [Tweet!]!
      	tweet(id: ID!): Tweet
    }
	# POST DELETE PUT
    type Mutation {
      	postTweet(text: String!, userId: ID!): Tweet!
      	deleteTweet(id: ID!): Boolean!
    }
`
  • resolvers
    • 누군가 field를 요청했을 때 실제로 호출될 함수
    • 하나의 객체이며, 나의 타입 정의와 같은 형태를 가져야 한다. (이름이 같아야 한다.)
    • Apollo 서버가 resolver function을 부를 때 argument를 준다.
      • 첫 번째는 root, 두 번째는 내가 전달하는 args이다.
      • root는 호출한 query의 값이라고 생각하면 된다.
      • 이 사진에서 23번째 줄에 console.log에 찍히는 값은 tweets 변수의 값이다.
    • 어떤 프로그래밍 언어를 사용하느냐에 따라서 달라진다.

전체 코드

  • 89번째 줄, 94번째 줄을 보면 tweets, users 변수에는 값이 없는 것을 확인할 수 있다.
  • 위 사진처럼 GraphQL을 사용할 때 일어나는 일
    • 처음으로 호출된건 Query로서 59번째 줄에 있는 allTweets()이다. 여기에서 tweet들의 list를 return 해준다.
    • 여기서 return 해주는 tweet는 40번째 줄의 type Tweet이다.
    • GraphQL은 type tweet를 확인하고 93번째 줄을 실행한다.
    • author이 변수 tweets에 없으므로 author resolver가 있어야 한다고 판단한다.
    • 94번째 줄의 author resolver을 발견하고 실행한다.
    • 여기에서 return 하는 것은 type User 이고 users에는 fullName이 없으므로 resolver에 89번째 줄을 실행한다.

profile
취준 개발자

0개의 댓글