Biến động
Query GraphQL bên dưới nhận biến $limit để biết số lượng bài viết cần lấy, và kiểu của biến, Int, phải được khai báo trong phép toán:
query GetPosts($limit: Int) {
posts(limit: $limit) {
id
title
}
}Đây là hành vi mong đợi trong GraphQL, trong đó chúng ta cung cấp giá trị biến trong một từ điển JSON được định nghĩa trong cùng một tài liệu:
{
"limit": 3
}Đây là hành vi "tĩnh", được chia sẻ bởi nhiều ngôn ngữ. Trong PHP, chẳng hạn, các đối số hàm có thể chỉ ra kiểu của chúng, như trong đoạn mã bên dưới, trong đó đầu vào $number được định nghĩa là một số nguyên:
function double(int $number): int
{
return $number * 2;
}Bây giờ, khi khai báo một biến bên trong thân hàm PHP, chúng ta không chỉ ra kiểu của nó; kiểu của biến được xác định bởi ngữ cảnh mà biến được sử dụng. Trong đoạn mã bên dưới, việc gán một giá trị số nguyên cho $double sẽ khiến biến này trở thành một số nguyên:
function double(int $number): int
{
// This var is an integer, but we don't need to declare it
$double = $number * 2;
return $double;
}Nhờ các directive tùy chỉnh, máy chủ GraphQL có thể cung cấp hành vi tương tự và hỗ trợ biến động, trong đó một biến động có giá trị được lấy khi phân giải query trên máy chủ, thay vì được client cung cấp.
Extension Multiple Query Execution của Gato GraphQL đi kèm với directive tùy chỉnh @export, cho phép xuất giá trị của một trường vào một biến (động), và sau đó chúng ta có thể đọc giá trị của biến này trong đối số trường từ một phép toán khác:
query ExportLoggedInUserName {
me {
name @export(as: "userName")
}
}
query GetPostsContainingString
@depends(on: "ExportLoggedInUserName")
{
posts(filter: { search: $userName }) {
id
title
}
}Biến $userName là động, và không cần định nghĩa kiểu của nó (String) trong phép toán sử dụng nó (GetPostsContainingString). Máy chủ GraphQL đã hiểu ngữ cảnh.
Nếu chúng ta cố gắng sử dụng giá trị biến với kiểu không khớp, như trong query sau (trong đó mong đợi một Int nhưng biến động là một String):
query ExportDynamicVariable {
_echo(value: "Hello world!") @export(as: "stringVar") # Exported: String
}
query UseVariable
@depends(on: "ExportDynamicVariable")
{
posts(
pagination: {
limit: $stringVar # Expected: Int, received: String
}
) {
id
}
}...thì máy chủ GraphQL thất bại khi ép kiểu giá trị, và trả về lỗi:
{
"errors": [
{
"message": "Cannot cast value 'Hello world!' for type 'Int'",
"locations": [
{
"line": 10,
"column": 13
}
],
"extensions": {
"path": [
"{limit: $stringVar}",
"(pagination: {limit: $stringVar})",
"posts(pagination: {limit: $stringVar}) { ... }",
"query UseVariable @depends(on: \"ExportDynamicVariable\") { ... }"
],
"type": "QueryRoot",
"field": "posts(pagination: {limit: $stringVar}) { ... }",
"id": "root",
"code": "gql@5.6.1[16]",
"specifiedBy": "https:\/\/spec.graphql.org\/draft\/#sec-Values-of-Correct-Type"
}
}
]
}Đặc tả GraphQL
Chức năng này hiện chưa là một phần của đặc tả GraphQL, nhưng đã được yêu cầu tại: