Trên trang này, bạn sẽ tìm hiểu tất cả những gì bạn cần biết về hệ thống loại GraphQL và cách hệ thống này mô tả dữ liệu nào có thể được truy vấn. Vì GraphQL có thể được sử dụng với bất kỳ khung phụ trợ hoặc ngôn ngữ lập trình nào, nên chúng tôi sẽ tránh xa các chi tiết triển khai cụ thể và chỉ nói về các khái niệm
Loại hệ thống #
Nếu bạn đã từng xem truy vấn GraphQL trước đây, thì bạn sẽ biết rằng ngôn ngữ truy vấn GraphQL về cơ bản là về việc chọn các trường trên đối tượng. Vì vậy, ví dụ, trong truy vấn sau
- Chúng tôi bắt đầu với một đối tượng "root" đặc biệt
- Chúng tôi chọn trường
5 trên đóhero[episode: Episode]: Character
- Đối với đối tượng được trả về bởi
5, chúng tôi chọn các trườnghero[episode: Episode]: Character
7 vàhero[episode: Episode]: Character
8hero[episode: Episode]: Character
Vì hình dạng của truy vấn GraphQL gần giống với kết quả, nên bạn có thể dự đoán kết quả truy vấn sẽ trả về mà không cần biết nhiều về máy chủ. Nhưng thật hữu ích khi có mô tả chính xác về dữ liệu mà chúng tôi có thể yêu cầu - chúng tôi có thể chọn những trường nào?
Mỗi dịch vụ GraphQL xác định một tập hợp các loại mô tả đầy đủ tập dữ liệu có thể có mà bạn có thể truy vấn trên dịch vụ đó. Sau đó, khi có truy vấn, chúng sẽ được xác thực và thực thi dựa trên lược đồ đó
Nhập ngôn ngữ#
Các dịch vụ GraphQL có thể được viết bằng bất kỳ ngôn ngữ nào. Vì chúng tôi không thể dựa vào một cú pháp ngôn ngữ lập trình cụ thể, như JavaScript, để nói về các lược đồ GraphQL, nên chúng tôi sẽ xác định ngôn ngữ đơn giản của riêng mình. Chúng tôi sẽ sử dụng "ngôn ngữ lược đồ GraphQL" - ngôn ngữ này tương tự như ngôn ngữ truy vấn và cho phép chúng tôi nói về các lược đồ GraphQL theo cách không phụ thuộc vào ngôn ngữ
Các loại đối tượng và trường #
Các thành phần cơ bản nhất của lược đồ GraphQL là các loại đối tượng, đại diện cho một loại đối tượng mà bạn có thể tìm nạp từ dịch vụ của mình và những trường mà nó có. Trong ngôn ngữ lược đồ GraphQL, chúng ta có thể biểu diễn nó như thế này
9hero[episode: Episode]: Character
Ngôn ngữ khá dễ đọc, nhưng hãy lướt qua nó để chúng ta có vốn từ vựng chung
0 là Loại đối tượng GraphQL, nghĩa là đây là loại có một số trường. Hầu hết các loại trong lược đồ của bạn sẽ là các loại đối tượnghero[episode: Episode]: Character
7 vàhero[episode: Episode]: Character
8 là các trường thuộc loạihero[episode: Episode]: Character
0. Điều đó có nghĩa làhero[episode: Episode]: Character
7 vàhero[episode: Episode]: Character
8 là những trường duy nhất có thể xuất hiện trong bất kỳ phần nào của truy vấn GraphQL hoạt động trên loạihero[episode: Episode]: Character
0hero[episode: Episode]: Character
6 là một trong những loại vô hướng tích hợp sẵn - đây là những loại phân giải thành một đối tượng vô hướng duy nhất và không thể có các lựa chọn phụ trong truy vấn. Chúng ta sẽ xem xét các loại vô hướng sauhero[episode: Episode]: Character
7 nghĩa là trường này không thể rỗng, nghĩa là dịch vụ GraphQL hứa sẽ luôn cung cấp cho bạn một giá trị khi bạn truy vấn trường này. Trong ngôn ngữ loại, chúng tôi sẽ đại diện cho những người có dấu chấm thanhero[episode: Episode]: Character
8 đại diện cho một mảng gồm các đối tượnghero[episode: Episode]: Character
9. Vì nó cũng không thể rỗng, nên bạn luôn có thể mong đợi một mảng [không có hoặc nhiều mục hơn] khi bạn truy vấn trườnghero[episode: Episode]: Character
8. Và vìhero[episode: Episode]: Character
1 cũng không thể rỗng, nên bạn luôn có thể mong đợi mọi phần tử của mảng là một đối tượngtype Human implements Character {
type Droid implements Character {
9hero[episode: Episode]: Character
Bây giờ bạn đã biết loại đối tượng GraphQL trông như thế nào và cách đọc những kiến thức cơ bản về ngôn ngữ loại GraphQL
Tranh luận#
Mọi trường trên loại đối tượng GraphQL có thể có 0 hoặc nhiều đối số, ví dụ như trường
3 bên dướitype Human implements Character {
type Droid implements Character {
4type Human implements Character {
type Droid implements Character {
Tất cả các đối số được đặt tên. Không giống như các ngôn ngữ như JavaScript và Python, nơi các hàm lấy danh sách các đối số được sắp xếp, tất cả các đối số trong GraphQL được chuyển theo tên cụ thể. Trong trường hợp này, trường
3 có một đối số được xác định,type Human implements Character {
type Droid implements Character {
6type Human implements Character {
type Droid implements Character {
Các đối số có thể là bắt buộc hoặc tùy chọn. Khi một đối số là tùy chọn, chúng ta có thể xác định một giá trị mặc định - nếu đối số
6 không được chuyển, nó sẽ được đặt thànhtype Human implements Character {
type Droid implements Character {
8 theo mặc địnhtype Human implements Character {
type Droid implements Character {
Các loại Truy vấn và Đột biến#
Hầu hết các loại trong lược đồ của bạn sẽ chỉ là các loại đối tượng bình thường, nhưng có hai loại đặc biệt trong một lược đồ
9hero[episode: Episode]: Character
Mọi dịch vụ GraphQL đều có loại
20 và có thể có hoặc không có loạihero[episode: Episode]: Character
21. Các loại này giống như một loại đối tượng thông thường, nhưng chúng đặc biệt vì chúng xác định điểm vào của mọi truy vấn GraphQL. Vì vậy, nếu bạn thấy một truy vấn giống nhưhero[episode: Episode]: Character
Điều đó có nghĩa là dịch vụ GraphQL cần phải có loại
22 với các trườnghero[episode: Episode]: Character
5 vàhero[episode: Episode]: Character
24hero[episode: Episode]: Character
25hero[episode: Episode]: Character
Các đột biến hoạt động theo cách tương tự - bạn xác định các trường thuộc loại
26 và các trường đó có sẵn dưới dạng các trường đột biến gốc mà bạn có thể gọi trong truy vấn của mìnhhero[episode: Episode]: Character
Điều quan trọng cần nhớ là ngoài trạng thái đặc biệt là "điểm vào" trong lược đồ, các loại
22 vàhero[episode: Episode]: Character
26 giống như bất kỳ loại đối tượng GraphQL nào khác và các trường của chúng hoạt động giống hệt nhauhero[episode: Episode]: Character
Các loại vô hướng#
Loại đối tượng GraphQL có tên và các trường, nhưng tại một số điểm, các trường đó phải phân giải thành một số dữ liệu cụ thể. Đó là nơi các loại vô hướng xuất hiện. chúng đại diện cho các lá của truy vấn
Trong truy vấn sau, các trường
7 vàhero[episode: Episode]: Character
8 sẽ phân giải thành các loại vô hướnghero[episode: Episode]: Character
Chúng tôi biết điều này vì những trường đó không có bất kỳ trường con nào - chúng là phần còn lại của truy vấn
GraphQL đi kèm với một tập hợp các loại vô hướng mặc định sẵn có
51. Số nguyên 32 bit có dấuhero[episode: Episode]: Character
52. Giá trị dấu phẩy động có độ chính xác kép đã kýhero[episode: Episode]: Character
6. Chuỗi ký tự UTF-8hero[episode: Episode]: Character
54.hero[episode: Episode]: Character
55 hoặchero[episode: Episode]: Character
56hero[episode: Episode]: Character
57. Loại vô hướng ID đại diện cho một mã định danh duy nhất, thường được sử dụng để tìm nạp lại một đối tượng hoặc làm khóa cho bộ đệm. Loại ID được sắp xếp theo thứ tự giống như Chuỗi;hero[episode: Episode]: Character
Trong hầu hết các triển khai dịch vụ GraphQL, cũng có một cách để chỉ định các loại vô hướng tùy chỉnh. Ví dụ, chúng ta có thể định nghĩa một loại
59hero[episode: Episode]: Character
9hero[episode: Episode]: Character
Sau đó, tùy thuộc vào quá trình triển khai của chúng tôi để xác định cách loại đó sẽ được tuần tự hóa, giải tuần tự hóa và xác thực. Ví dụ: bạn có thể chỉ định rằng loại
59 phải luôn được đánh số thứ tự thành dấu thời gian số nguyên và khách hàng của bạn nên biết để mong đợi định dạng đó cho bất kỳ trường ngày nàohero[episode: Episode]: Character
Kiểu liệt kê#
Còn được gọi là Enums, các kiểu liệt kê là một loại vô hướng đặc biệt được giới hạn trong một tập hợp các giá trị được phép cụ thể. Điều này cho phép bạn
- Xác thực rằng mọi đối số thuộc loại này là một trong những giá trị được phép
- Giao tiếp thông qua hệ thống loại rằng một trường sẽ luôn là một trong các tập giá trị hữu hạn
Đây là định nghĩa enum có thể trông như thế nào trong ngôn ngữ lược đồ GraphQL
9hero[episode: Episode]: Character
Điều này có nghĩa là bất cứ nơi nào chúng tôi sử dụng loại
9 trong lược đồ của mình, chúng tôi mong đợi nó chính xác là một trong sốhero[episode: Episode]: Character
54,hero[episode: Episode]: Character
55 hoặchero[episode: Episode]: Character
56hero[episode: Episode]: Character
Lưu ý rằng việc triển khai dịch vụ GraphQL bằng các ngôn ngữ khác nhau sẽ có cách xử lý enum theo ngôn ngữ riêng của chúng. Trong các ngôn ngữ hỗ trợ enums với tư cách là công dân hạng nhất, việc triển khai có thể tận dụng lợi thế đó; . Tuy nhiên, những chi tiết này không bị rò rỉ ra ngoài máy khách, máy khách có thể hoạt động hoàn toàn theo tên chuỗi của các giá trị enum
Danh sách và Non-Null#
Các loại đối tượng, vô hướng và enum là những loại duy nhất bạn có thể xác định trong GraphQL. Nhưng khi bạn sử dụng các loại trong các phần khác của lược đồ hoặc trong các khai báo biến truy vấn của mình, bạn có thể áp dụng các công cụ sửa đổi loại bổ sung ảnh hưởng đến việc xác thực các giá trị đó. Hãy xem một ví dụ
9hero[episode: Episode]: Character
Ở đây, chúng tôi đang sử dụng loại
6 và đánh dấu nó là Non-Null bằng cách thêm dấu chấm than,hero[episode: Episode]: Character
59 sau tên loại. Điều này có nghĩa là máy chủ của chúng tôi luôn mong đợi trả về một giá trị khác null cho trường này và nếu nó kết thúc bằng một giá trị null sẽ thực sự gây ra lỗi thực thi GraphQL, cho khách hàng biết rằng đã xảy ra sự cốhero[episode: Episode]: Character
Công cụ sửa đổi loại Non-Null cũng có thể được sử dụng khi xác định đối số cho một trường, điều này sẽ khiến máy chủ GraphQL trả về lỗi xác thực nếu giá trị null được truyền dưới dạng đối số đó, cho dù trong chuỗi GraphQL hay trong các biến
Danh sách hoạt động theo cách tương tự. Chúng ta có thể sử dụng công cụ sửa đổi kiểu để đánh dấu một kiểu là
70, điều này cho biết rằng trường này sẽ trả về một mảng kiểu đó. Trong ngôn ngữ lược đồ, điều này được biểu thị bằng cách đặt loại trong dấu ngoặc vuông,hero[episode: Episode]: Character
71 vàhero[episode: Episode]: Character
72. Nó hoạt động tương tự đối với các đối số, trong đó bước xác thực sẽ mong đợi một mảng cho giá trị đóhero[episode: Episode]: Character
Các công cụ sửa đổi Non-Null và List có thể được kết hợp. Ví dụ, bạn có thể có một List of Non-Null Strings
9hero[episode: Episode]: Character
Điều này có nghĩa là bản thân danh sách có thể là null, nhưng nó không thể có bất kỳ thành viên null nào. Ví dụ, trong JSON
9hero[episode: Episode]: Character
Bây giờ, giả sử chúng ta đã xác định Danh sách các chuỗi không có giá trị
9hero[episode: Episode]: Character
Điều này có nghĩa là bản thân danh sách không thể rỗng, nhưng nó có thể chứa các giá trị null
9hero[episode: Episode]: Character
Bạn có thể tùy ý lồng bất kỳ số lượng công cụ sửa đổi Non-Null và List nào, theo nhu cầu của bạn
Giao diện #
Giống như nhiều loại hệ thống, GraphQL hỗ trợ các giao diện. Giao diện là một loại trừu tượng bao gồm một tập hợp các trường nhất định mà một loại phải bao gồm để triển khai giao diện
Ví dụ: bạn có thể có giao diện
0 đại diện cho bất kỳ nhân vật nào trong bộ ba phim Chiến tranh giữa các vì saohero[episode: Episode]: Character
9hero[episode: Episode]: Character
Điều này có nghĩa là bất kỳ loại nào triển khai
0 đều cần phải có các trường chính xác này, với các đối số và kiểu trả về nàyhero[episode: Episode]: Character
Ví dụ: đây là một số loại có thể triển khai
0hero[episode: Episode]: Character
81hero[episode: Episode]: Character
Bạn có thể thấy rằng cả hai loại này đều có tất cả các trường từ giao diện
0, nhưng cũng có các trường bổ sung,hero[episode: Episode]: Character
83,hero[episode: Episode]: Character
84 vàhero[episode: Episode]: Character
85, dành riêng cho loại ký tự cụ thể đóhero[episode: Episode]: Character
Các giao diện hữu ích khi bạn muốn trả về một đối tượng hoặc tập hợp các đối tượng, nhưng chúng có thể thuộc nhiều loại khác nhau
Ví dụ: lưu ý rằng truy vấn sau tạo ra lỗi
Trường
5 trả về loạihero[episode: Episode]: Character
0, có nghĩa là nó có thể làhero[episode: Episode]: Character
88 hoặchero[episode: Episode]: Character
89 tùy thuộc vào đối sốhero[episode: Episode]: Character
90. Trong truy vấn trên, bạn chỉ có thể yêu cầu các trường tồn tại trên giao diệnhero[episode: Episode]: Character
0, không bao gồmhero[episode: Episode]: Character
85hero[episode: Episode]: Character
Để yêu cầu một trường trên một loại đối tượng cụ thể, bạn cần sử dụng một đoạn nội tuyến
Tìm hiểu thêm về điều này trong phần đoạn nội tuyến trong hướng dẫn truy vấn
các loại liên minh #
Các loại liên kết rất giống với giao diện, nhưng chúng không chỉ định bất kỳ trường chung nào giữa các loại
93hero[episode: Episode]: Character
Bất cứ nơi nào chúng tôi trả về loại
94 trong lược đồ của mình, chúng tôi có thể nhận được mộthero[episode: Episode]: Character
88, mộthero[episode: Episode]: Character
89 hoặc mộthero[episode: Episode]: Character
97. Lưu ý rằng các thành viên của một loại liên kết cần phải là các loại đối tượng cụ thể;hero[episode: Episode]: Character
Trong trường hợp này, nếu bạn truy vấn một trường trả về loại kết hợp
94, bạn cần sử dụng một đoạn nội tuyến để có thể truy vấn bất kỳ trường nàohero[episode: Episode]: Character
Trường
99 phân giải thànhhero[episode: Episode]: Character
6 cho phép bạn phân biệt các loại dữ liệu khác nhau trên máy kháchhero[episode: Episode]: Character
Ngoài ra, trong trường hợp này, vì
88 vàhero[episode: Episode]: Character
89 chia sẻ một giao diện chung [hero[episode: Episode]: Character
0], bạn có thể truy vấn các trường chung của chúng ở một nơi thay vì phải lặp lại cùng một trường trên nhiều loạihero[episode: Episode]: Character
9hero[episode: Episode]: Character
Lưu ý rằng
7 vẫn được chỉ định trênhero[episode: Episode]: Character
97 vì nếu không, nó sẽ không hiển thị trong kết quả dohero[episode: Episode]: Character
97 không phải làhero[episode: Episode]: Character
0hero[episode: Episode]: Character
Loại đầu vào #
Cho đến nay, chúng ta chỉ nói về việc chuyển các giá trị vô hướng, như enum hoặc chuỗi, dưới dạng đối số vào một trường. Nhưng bạn cũng có thể dễ dàng vượt qua các đối tượng phức tạp. Điều này đặc biệt có giá trị trong trường hợp đột biến, nơi bạn có thể muốn chuyển toàn bộ đối tượng được tạo. Trong ngôn ngữ lược đồ GraphQL, các loại đầu vào trông giống hệt như các loại đối tượng thông thường, nhưng với từ khóa
09 thay vìhero[episode: Episode]: Character
00hero[episode: Episode]: Character
9hero[episode: Episode]: Character
Đây là cách bạn có thể sử dụng loại đối tượng đầu vào trong một đột biến
Các trường trên một loại đối tượng đầu vào có thể tự tham chiếu đến các loại đối tượng đầu vào, nhưng bạn không thể kết hợp các loại đầu vào và đầu ra trong lược đồ của mình. Các loại đối tượng đầu vào cũng không thể có đối số trên các trường của chúng