티스토리 뷰

Dev/GraphQL

[GraphQL] GraphQL API 구현 part 1

j.y.eunseo 2023. 3. 1. 22:12

# GraphQL API setup

Apollo server (Node.js 서버와 비슷한 서버로 GraphQL specification을 구현하는 서버)를 사용해서 GraphQL API를 만들어보자.

$ npm init -y
$ npm install apollo-server graphql
$ npm install nodemon -D

** nodemon은 옵션이며 필수로 설치할 필요는 없다.

    nodemon을 사용 시 자동 서버 재시작으로 바로바로 업데이트된다는 장점이 있다.

 

### package.json 설정

{
  "name": "tweetql",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "dev": "nodemon server.js",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "apollo-server": "^3.11.1",
    "graphql": "^16.6.0"
  },
  "devDependencies": {
    "nodemon": "^2.0.20"
  },
  "type": "module"
}

### server.js 파일 생성

import { ApolloServer, gql } from "apollo-server";

** import 형태로 사용하고자 한다면 package.json"type":"module"을 설정해야하며, 

    설정하지 않을 시 require를 사용해야한다. ( const { ApolloServer, gql  = require("apollo-server"); )

 

import { ApolloServer, gql } from "apollo-server";

const server = new ApolloServer({});

server.listen().then(({ url }) => {
  console.log(`Running in ${url}`);
});

아폴로 서버를 생성하고 실행하면 다음과 같은 에러가 발생한다.

Error: Apollo Server requires either an existing schema, modules or typeDefs

typeDefs란 무엇일까?

 

 

# Query Type

상단의 에러가 발생하는 이유는 graphQL이 데이터의 형태를 미리 알고 있어야 하기 때문이다.

 graphQL은 많은 type들의 집합으로 data의 type을 설정해주어야 한다.

 

## Schema Definition Language

스키마(Schema)란 type definitions의 모음으로 객체들을 정의하는 필드이며, Query 루트 타입은 필수적으로 사용해야 한다.

 

Query안의 객체들을 REST API와 비교하자면 GET URL과 같은 개념이다.

GET /title
GET /useName
GET /intro

const typeDefs = gql`
  type Query {
    title: String
    useName: String
  }
`; //Schema Definition Language

 

server.js 코드를 작성하고 실행하면 아폴로 서버 페이지가 성공적으로 나오는 결과를 볼 수 있다.

 

 

# Scalar and Root Type

스키마 내에서 자유롭게 필드를 정의할 수도 있다.

 

1. Tweet 객체 타입을 정의한 후 allTweets에서 Tweet 객체 배열을 반환할 수 있다.

const typeDefs = gql`
  type Tweet {
    id: ID
    text: String
  }

  type Query {
    allTweets: [Tweet]
  }
`;

 

2. 타입 안에 타입 객체를 사용할 수 있다

const typeDefs = gql`
  type User {
    id: ID
    userName: String
  }
  type Tweet {
    id: ID
    text: String
    author: User
  }

  type Query {
    allTweets: [Tweet]
  }
`;

Tweet는 하나의 User를 가지며 tweets는 Tweet 배열을 가지고 있다.

 

3. argument를 설정하여 해당 데이터애 일치한 객체를 반환하도록 설정한다.

예) GET /movies/{id} tweet(id: ID): Tweet

 

const typeDefs = gql`
  type User {
    id: ID
    userName: String
  }
  type Tweet {
    id: ID
    text: String
    author: User
  }

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

 

# Mutation Type

Query는 대부분 GET Request를 담당한다. 그렇다면 POST, PUT, DELETE와 같은 Request는 어떻게 설정할까?

서버 측 데이터를 수정하는 모든 작업은 Mutation을 통해 요청을 보낼 수 있다. 

 

const typeDefs = gql`
  type User {
    id: ID
    userName: 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
  }
`;

💡 사용자가 데이터를 받아오는 작업은 Query에서, 데이터를 생성,수정,삭제와 같은 작업은 Mutation에서

 

# Nun Nullable Fields

이전에서 작업한 GraphQL query를 실행 시 null 값을 리턴하는 결과를 볼 수 있다.

이와 같이 에러 없이 null 값을 반환하는 이유는 Nullable field이기 때문이다. (value or Null)

'!'를 사용하여 Nun-Null로 표시할 수 있다. (required와 같은 개념)

Non-Null로 표시하게 되면 서버가 항상 이 필드에 대해 null이 아닌 값을 반환할 것이며, null 값을 얻게 된다면 클라이언트에게 문제가 있음을 알려준다.

const typeDefs = gql`
  type User {
    id: ID!
    userName: String!
  }
  
  type Tweet {
    id: ID!
    text: String!
    author: User!
  }

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

 

참고

https://graphql-kr.github.io/learn/schema/

'Dev > GraphQL' 카테고리의 다른 글

[GraphQL] GraphQL을 시작하기 전  (0) 2023.03.01
댓글
«   2025/07   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31
최근에 올라온 글