반응형

 

 

Graphql Schema에서 정의하는 유형은 아래가 전부입니다

  • Scalar
  • Object
  • Input
  • Enum
  • Union
  • Interface

 

📝Scalar

기본 타입들이 정의되어있습니다

  • Int
    • 부호 있는 32비트 정수
  • Float
    • 부호 있는 배정밀도 부동 소수점 값
  • String
    • UTF‐8 문자 시퀀스
  • Boolean
    • true또는false
  • ID
    • 객체를 다시 가져오는 데 자주 사용되거나 캐시의 키로 사용되는 고유 식별자입니다

 

그 외에는 커스텀으로 만들 수 있는데 자세한건 아래 링크를 참조하기 바랍니다

참고로 npm에 있는 bigInt, Decimal등은 공식적으로 지원하는 게 아닌 어떤 사람이 만든 것입니다

https://www.apollographql.com/docs/apollo-server/schema/custom-scalars/

 

 

 

📝Object

Object Type은 스키마에서 정의하는 대부분이다 API요청을 위한 API이름과 반환값 또는 Scalar들로 이루어진 새로운 타입을 정의합니다

type Author {
  name: String
  books: [Book] # []으로 리스트 정의
}

type Query {
  books: [Book]
  authors: [Author]
}
type Mutation {
  addBook(title: String, author: String): Book
}
type Subscription {
  postCreated: Post
}

 

 

 

📝Input

Object Type에 파라미터가 필요한 경우 Scalar타입으로 다 적을수도 있지만 따로 분리 후 Input Type을 만들어서 따로 관리 및 재사용할 수 있습니다

input BlogPostContent {
  title: String
  body: String
}
# Input 사용 예제
type Mutation {
  createBlogPost(content: BlogPostContent!): Post
  updateBlogPost(id: ID!, content: BlogPostContent!): Post
}

 

 

📝Enum

말 그대로 Enum Type이다

enum AllowedColor {
  RED
  GREEN
  BLUE
}

 

📝Union

Union은 정의한 것만 허용한다라는 의미입니다

union SearchResult = Book | Author

type Book {
  title: String!
}

type Author {
  name: String!
}

type Query {
  search(contains: String): [SearchResult!]
}

위에 코드를 보면 search에 대한 Query는 반환 값이 Book Type이던가 Author Type이여야합니다

근데 문제점이 생기는데 search는 어떤 타입을 반환할지 몰라 어떤 필드를 요청할지 모릅니다 이에 대한 해결법은 아래와 같습니다

 

방법1

query GetSearchResults {
  search(contains: "Shakespeare") {
    __typename
    ... on Book {
      title
    }
    ... on Author {
      name
    }
  }
}

Book일 경우 title을 반환하고 Author일 경우 name을 반환합니다

 

방법2 (resolverType)

const resolvers = {
  SearchResult: {
    __resolveType(obj, contextValue, info){
      // Only Author has a name field
      if(obj.name){
        return 'Author';
      }
      // Only Book has a title field
      if(obj.title){
        return 'Book';
      }
      return null; // GraphQLError is thrown
    },
  },
  Query: {
    search: () => { ... }
  },
};

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

const { url } = await startStandaloneServer(server);

console.log(`🚀  Server ready at: ${url}`);

resolver에서는 이런식으로 처리합니

 

📝Interface

interface는 Type과 유사한데 상속받을 수 있습니다

interface Book {
  title: String!
  author: Author!
}

type Textbook implements Book {
  title: String! # Must be present
  author: Author! # Must be present
  courses: [Course!]!
}

union과 동일하게 interface를 반환타입으로 가지는 경우에도 추가적인 필드에 대해서 어떤 걸 가질지 모른다 이에 대한 처리 방법은 아래와 같다

 

방법1

query GetBooks {
  books {
    __typename
    title
    ... on Textbook {
      courses {
        # Only present in Textbook
        name
      }
    }
    ... on ColoringBook {
      colors # Only present in ColoringBook
    }
  }
}

 

방법2 (resolverType)

const resolvers = {
  Book: {
    __resolveType(book, contextValue, info){
      // Only Textbook has a courses field
      if(book.courses){
        return 'Textbook';
      }
      // Only ColoringBook has a colors field
      if(book.colors){
        return 'ColoringBook';
      }
      return null; // GraphQLError is thrown
    },
  },
  Query: {
    books: () => { ... }
  },
};

 

📝Directives

type ExampleType {
  oldField: String @deprecated(reason: "Use `newField`.")
  newField: String
}

@deprecated로 사용 금지에 대한 기능과 문서를 작성할 수 있고 필요한 경우 사용자 정의 지시어를 만들 수 있다

 

https://www.apollographql.com/docs/apollo-server/schema/directives#custom-directives

반응형