- vừa được xem lúc

GraphQL SDL - Schema Definition Language Phần 2

0 0 65

Người đăng: Vuong Huong

Theo Viblo Asia

Nối tiếp Phần một về Schema Difinition Language của GraphQL, bài viết này trình bày tiếp các khái niệm được sử dụng để định nghĩa GraphQL Schema

1. Interfaces

  • Cũng giống như khái niệm Interface ở các language khác, trong GraphQL, một Interface là một asbstract type có thể bao gồm một tập nhất định các field mà các type khi implement nó cũng phải bao gồm các field đó.

  • Ví dụ, bạn có một interface Character đại diện cho bất kì nhân vật nào trong Star Wars

    interface Character { id: ID! name: String! friends: [Character] appearsIn: [Episode]!
    }
    

    Bất kì type nào mà Implements Characters cần phải có đầy đủ các trường trên với cùng tham số hay cùng type.

  • Ví dụ, các type sáu đây có thể implement Character

    type Human implements Character { id: ID! name: String! friends: [Character] appearsIn: [Episode]! starships: [Starship] totalCredits: Int
    } type Droid implements Character { id: ID! name: String! friends: [Character] appearsIn: [Episode]! primaryFunction: String
    }
    

    Cả 3 type này đều có tất cả các trường từ Character interface, đồng thời cũng có các trường bổ sung như totalCredits, starships, primaryFunction giúp xác định các loại Character cụ thể.

  • Interface hữu ích khi mà bạn muốn trả về một object hay là một bộ các object, nhưng chúng lại có các trường khác nhau.

  • Ví dụ, câu query sau sẽ sinh ra lỗi

    QUERY DEFINITION

    type Query { hero(episode: Episode): Character
    }
    

    CLIENT CALL QUERY

    query HeroForEpisode($ep: Episode!) { hero(episode: $ep) { name ... on Droid { primaryFunction } }
    }
    

    VARIABLES

    { "ep": "JEDI"
    }
    

    RESULT

    { "errors": [ { "message": "Cannot query field \"primaryFunction\" on type \"Character\". Did you mean to use an inline fragment on \"Droid\"?", "locations": [ { "line": 4, "column": 5 } ] } ]
    }
    
  • Trường hero trả về một kiểu Character, nó có thể là Human hay Droid tùy thuộc vào biến episode. Trong câu query trên bạn chỉ có thể chỉ định trả về những field mà tồn tại trong Character interface, như vậy sẽ không có primaryFunction

  • Để yêu cầu trả về các trường trong một object type cụ thể, sử dụng inline fragments

2. Union types

  • Ví dụ

    union SearchResult = Human | Droid | Starship
    
  • Bất cứ khi nào chúng ta trả về một loại Search Result trong schema, SearchResult này có thể là một Human, Droid, hoặc một Starship. Các thành phần của một union type cần phải là một loại đối tượng cụ thể, không được là một interface hay là một union khác

  • Khi phía client query một field mà trả về một union type là SearchResult, chúng ta cần phải sử dụng inline fragment để có thể query bất kì trường nào.

    CLIENT QERRY

    { search(text: "an") { __typename ... on Human { name height } ... on Droid { name primaryFunction } ... on Starship { name length } }
    }
    

    RESULT

     "data": { "search": [ { "__typename": "Human", "name": "Han Solo", "height": 1.8 }, { "__typename": "Human", "name": "Leia Organa", "height": 1.5 }, { "__typename": "Starship", "name": "TIE Advanced x1", "length": 9.2 } ] }
    }
    
  • Trường __typename là một String giúp bạn phân biệt sự khác nhau giữa các object type ở Client

  • Ở ví dụ này, vì HumanDroid cùng implement một interface chung là Character nên bạn có thể query những trường chung của 2 object type này ở chỉ một chỗ mà không cần lặp lại các trường giống nhau ở mỗi type, ví dụ sau đây cho kết quả như bên trên:

    { search(text: "an") { __typename ... on Character { name } ... on Human { height } ... on Droid { primaryFunction } ... on Starship { name length } }
    }
    

    Lưu ý: Trường name vẫn phải được chỉ định đối với Starship bởi Starship không phải là một Character

3.Input types

  • Từ đầu đến giờ, chúng ta chỉ nói về truyền vào một field các argument thuộc về kiểu scalar như enums hay strings. Tuy nhiên bạn có thể truyền argument là một object phức tạp. Điều này cực kì hữu ích khi bạn muốn truyền vào toàn bộ object để tạo cái gì đó.

  • Trong GraphQL SDL, input types nhìn sẽ giống một object types thông tường nhưng với keyword input thay vì type

    input ReviewInput { stars: Int! commentary: String
    }
    
  • Ví dụ sử dụng input type trong một mutation

    MUTATION DEFINITION

    mutation CreateReviewForEpisode($ep: Episode!, $review: ReviewInput!) { createReview(episode: $ep, review: $review) { stars commentary }
    }
    

    VARIABLES

    { "ep": "JEDI", "review": { "stars": 5, "commentary": "This is a great movie!" }
    }
    

    RESULT

    { "data": { "createReview": { "stars": 5, "commentary": "This is a great movie!" } }
    }
    

4. Kết luận

Bình luận

Bài viết tương tự

- vừa được xem lúc

GraphQL SDL - Schema Definition Language Phần 1

1. GraphQL Schema Difinition Language là gì. SDL là một ngôn ngữ có cú pháp rất đơn giản, dễ hiểu đồng thời cũng rất mạnh mẽ và trực quan giúp định nghĩa schema một các cô đọng nhất. id: String.

0 0 49

- vừa được xem lúc

Mini Apollo GraphQL React client - server

Chào anh em, lại là mình đây . Hôm nay mình lại tiếp tục đi đến một chủ đề khá thú vị, cực kì phù hợp cho các anh em thích nghịch ngợm và cũng đơn giản để có thiển triển khai các pet project trong tương lai.

0 0 23

- vừa được xem lúc

Dgraph Graph Database in 100 Seconds

Learn the fundamentals of Dgraph - an open-source Graph Database that implements GraphQL as its query language https://bit.ly/3qc2Nac. . #database #graphql #100SecondsOfCode.

0 0 30

- vừa được xem lúc

Thực thi truy vấn GraphQL trên Server

1. Giới thiệu chung. . .

0 0 90

- vừa được xem lúc

Hasura in 100 Seconds

Learn how Hasura can instantly turn your SQL database into a GraphQL API. https://github.com/hasura/graphql-engine. .

0 0 30

- vừa được xem lúc

Bắt đầu với GraphQL và Spring Boot

1. Giới thiệu:. GraphQL là một khái niệm tương đối mới của Facebook được dự tính sẽ là giải pháp thay thế REST cho các API Web. 2.

0 0 58