GraphQL all in one
Queries and Mutations
http://graphql.org/learn/queries/
On this page, you'll learn in detail about how to query a GraphQL server.
Fields
{
hero {
name
}
}
{
"data": {
"hero": {
"name": "R2-D2"
}
}
}
{
hero {
name
# Queries can have comments!
friends {
name
}
}
}
{
"data": {
"hero": {
"name": "R2-D2",
"friends": [
{
"name": "Luke Skywalker"
},
{
"name": "Han Solo"
},
{
"name": "Leia Organa"
}
]
}
}
}
Arguments
{
human(id: "1000") {
name
height
}
}
{
"data": {
"human": {
"name": "Luke Skywalker",
"height": 1.72
}
}
}
{
human(id: "1000") {
name
height(unit: FOOT)
# FOOT 英尺
# https://en.wikipedia.org/wiki/Foot_(unit)
}
}
{
human(id: "1000") {
name
# height # default unit === METER
# height(unit: METER) # 1.72
height(unit: FOOT) # 5.6430448
appearsIn
friends {
__typename
name
appearsIn
}
starships{
id
}
friendsConnection{
pageInfo{
startCursor
endCursor
hasNextPage
}
}
}
}
{
"data": {
"human": {
"name": "Luke Skywalker",
"height": 5.6430448
}
}
}
Aliases
{
empireHero: hero(episode: EMPIRE) {
name
}
jediHero: hero(episode: JEDI) {
name
}
}
{
"data": {
"empireHero": {
"name": "Luke Skywalker"
},
"jediHero": {
"name": "R2-D2"
}
}
}
Fragments
{
leftComparison: hero(episode: EMPIRE) {
...comparisonFields
}
rightComparison: hero(episode: JEDI) {
...comparisonFields
}
}
fragment comparisonFields on Character {
name
appearsIn
friends {
name
}
}
{
"data": {
"leftComparison": {
"name": "Luke Skywalker",
"appearsIn": [
"NEWHOPE",
"EMPIRE",
"JEDI"
],
"friends": [
{
"name": "Han Solo"
},
{
"name": "Leia Organa"
},
{
"name": "C-3PO"
},
{
"name": "R2-D2"
}
]
},
"rightComparison": {
"name": "R2-D2",
"appearsIn": [
"NEWHOPE",
"EMPIRE",
"JEDI"
],
"friends": [
{
"name": "Luke Skywalker"
},
{
"name": "Han Solo"
},
{
"name": "Leia Organa"
}
]
}
}
}
Variables
query
query HeroNameAndFriends($episode: Episode) {
hero(episode: $episode) {
name
friends {
name
}
}
}
{
"episode": "JEDI"
}
{
"data": {
"hero": {
"name": "R2-D2",
"friends": [
{
"name": "Luke Skywalker"
},
{
"name": "Han Solo"
},
{
"name": "Leia Organa"
}
]
}
}
}
Variable definitions
($episode: Episode)
# It lists all of the variables, prefixed by $, followed by their type, in this case `Episode`.
# All declared variables must be either scalars, enums, or input object types.
# 所有声明的变量必须是`标量`,枚举或输入对象类型。
# Variable definitions can be optional or required.
# In the case above, since there isn't an `!` next to the Episode type, it's optional.
query HeroNameAndFriends($episode: Episode) {
hero(episode: $episode) {
name
friends {
name
}
}
}
Default variables
query HeroNameAndFriends($episode: Episode = "JEDI") {
hero(episode: $episode) {
name
friends {
name
}
}
}
# When default values are provided for all variables, you can call the query without passing any variables.
# If any variables are passed as part of the variables dictionary, they will override the defaults.
Operation name
# One thing we also saw in the example above is that our query has acquired an operation name.
# Up until now, we have been using a `shorthand syntax` where we omit both the `query keyword` and the `query name`,
# For example, in JavaScript we can easily work only with anonymous functions,
# but when we give a function a name, it's easier to track it down, debug our code, and log when it's called.
Directives
query Hero($episode: Episode, $withFriends: Boolean!) {
hero(episode: $episode) {
name
friends @include(if: $withFriends) {
name
}
}
}
# The core GraphQL specification includes exactly two directives,
# which must be supported by any spec-compliant GraphQL server implementation:
# @include(if: Boolean) Only include this field in the result if the argument is true.
# @skip(if: Boolean) Skip this field if the argument is true.
{
"episode": "JEDI",
"withFriends": false
}
{
"episode": "JEDI",
"withFriends": true
}
{
"data": {
"hero": {
"name": "R2-D2"
}
}
}
{
"data": {
"hero": {
"name": "R2-D2",
"friends": [
{
"name": "Luke Skywalker"
},
{
"name": "Han Solo"
},
{
"name": "Leia Organa"
}
]
}
}
}
Mutations
mutation
mutation CreateReviewForEpisode($ep: Episode!, $review: ReviewInput!) {
createReview(episode: $ep, review: $review) {
stars
commentary
}
}
# This can be useful for fetching the new state of an object after an update.
# This is especially useful when mutating existing data,
# for example, when incrementing a field, since we can mutate and query the new value of the field with one request.
# in this example, the review variable we passed in is not a `scalar`.
# It's an `input object type`, a special kind of object type that can be passed in as an argument.
{
"ep": "JEDI",
"review": {
"stars": 5,
"commentary": "This is a great movie!"
}
}
{
"data": {
"createReview": {
"stars": 5,
"commentary": "This is a great movie!"
}
}
}
Multiple fields in mutations
# A mutation can contain multiple fields, just like a query.
# There's one important distinction between queries and mutations, other than the name:
# While query fields are executed `in parallel`, mutation fields run `in series`, one after the other.
# This means that if we send two incrementCredits mutations in one request,
# the first is guaranteed to finish before the second begins,
# ensuring that we don't end up with a `race condition` with ourselves.
# 竞争条件
Inline Fragments
http://graphql.org/learn/schema/#interfaces
http://graphql.org/learn/schema/#union-types
# If you are querying a field that returns an interface or a union type,
# you will need to use `inline fragments` to access data on the `underlying concrete type`.
# 如果要查询一个返回一个`接口`或一个`联合类型`的字段,则需要使用内联片段来访问`底层具体类型`的数据。
query HeroForEpisode($ep: Episode!) {
hero(episode: $ep) {
name
... on Droid {
primaryFunction
}
... on Human {
height
}
}
}
{
"ep": "JEDI"
}
{
"data": {
"hero": {
"name": "R2-D2",
"primaryFunction": "Astromech"
}
}
}
Meta fields
# GraphQL allows you to request `__typename`, a meta field,
# at any point in a query to get the name of the object type at that point.
{
search(text: "an") {
__typename
... on Human {
name
}
... on Droid {
name
}
... on Starship {
name
}
}
}
# In the above query, search returns a `union type` that can be one of three options.
# It would be impossible to `tell apart` the different types from the client without the `__typename` field.
# 分辨
# GraphQL services provide a few meta fields, the rest of which are used to expose the `Introspection` system.
# GraphQL服务提供了一些元字段,其余的用于公开“内省”系统。
# introspection, self-examination 内省 自我检查
{
"data": {
"search": [
{
"__typename": "Human",
"name": "Han Solo"
},
{
"__typename": "Human",
"name": "Leia Organa"
},
{
"__typename": "Starship",
"name": "TIE Advanced x1"
}
]
}
}
Schemas and Types
http://graphql.org/learn/schema
On this page, you'll learn all you need to know about the GraphQL type system and how it describes what data can be queried.
Type system
# the GraphQL query language is basically about selecting fields on objects.
{
hero {
name
appearsIn
}
}
{
"data": {
"hero": {
"name": "R2-D2",
"appearsIn": [
"NEWHOPE",
"EMPIRE",
"JEDI"
]
}
}
}
Type language
# GraphQL services can be written in any language.
# We'll use the "GraphQL schema language"
# it's similar to the query language, and allows us to talk about GraphQL schemas in a `language-agnostic` way.
# `与语言无关`
# agnostic 不可知
Object types and fields
type Character {
name: String!
appearsIn: [Episode]!
}
# `Character` is a `GraphQL Object Type`, meaning it's a type with some fields.
# Most of the types in your schema will be object types.
# `name` and `appearsIn` are `fields` on the `Character` type.
# That means that name and appearsIn are the only fields that can appear in any part of a GraphQL query that operates on the Character type.
# `String` is one of the built-in `scalar types`
# these are types that resolve to a single scalar object, and can't have sub-selections in the query.
# scalar types, 标量类型
# `String!` means that the field is `non-nullable`,
# meaning that the GraphQL service promises to always give you a value when you query this field.
# exclamation mark, 感叹号
Arguments
type Starship {
id: ID!
name: String!
length(unit: LengthUnit = METER): Float
# defined argument: `unit`
# default value: `METER`
# scalar types: `Float`
}
# All arguments are named.
# all arguments in GraphQL are passed by name specifically.
# In this case, the `length` field has one defined argument, `unit`.
# Arguments can be either required or optional.
# When an argument is optional, we can define a `default value` - if the unit argument is not passed, it will be set to `METER` by default.
The Query and Mutation types
Most types in your schema will just be normal object types, but there are two types that are special within a schema:
# Every GraphQL service has a `query type` and may or may not have a `mutation type`.
schema {
query: Query
mutation: Mutation
}
# These types are the same as a regular object type, but they are special because they define the entry point of every GraphQL query.
query {
hero {
name
}
droid(id: "2000") {
name
}
}
# That means that the GraphQL service needs to have a Query type with hero and droid fields:
type Query {
hero(episode: Episode): Character
droid(id: ID!): Droid
}
# Mutations work in a similar way
# you define fields on the Mutation type, and those are available as the root mutation fields you can call in your query.
{
"data": {
"hero": {
"name": "R2-D2"
},
"droid": {
"name": "C-3PO"
}
}
}
Scalar types
# A GraphQL object type has a name and fields, but at some point those fields have to resolve to some concrete data.
# 一个 GraphQL 对象类型具有名称和字段,但在某些时候,这些字段必须解析为某些具体数据。
{
hero {
name
appearsIn
}
}
# GraphQL comes with a set of default scalar types out of the box:
# Int: A signed 32‐bit integer.
# Float: A signed double-precision floating-point value.
# String: A UTF‐8 character sequence.
# Boolean: true or false.
# ID: The ID scalar type represents a unique identifier, often used to refetch an object or as the key for a cache.
# The ID type is serialized in the same way as a String;
# however, defining it as an ID signifies that it is not intended to be human‐readable.
# In most GraphQL service implementations, there is also a way to specify custom scalar types.
# Then it's up to our implementation to define how that type should be serialized, deserialized, and validated.
`scalar Date`
{
"data": {
"hero": {
"name": "R2-D2",
"appearsIn": [
"NEWHOPE",
"EMPIRE",
"JEDI"
]
}
}
}
Enumeration types
Enums, enumeration types are a special kind of scalar that is restricted to a particular set of allowed values.
enum Episode {
NEWHOPE
EMPIRE
JEDI
}
# This means that wherever we use the type Episode in our schema, we expect it to be exactly one of NEWHOPE, EMPIRE, or JEDI.
# in a language like JavaScript with no enum support, these values might be internally mapped to a set of integers.
# 在没有枚举支持的JavaScript语言中,这些值可能在内部映射到一组整数。
Lists and Non-Null
# But when you use the types in other parts of the schema, or in your query variable declarations,
# you can apply additional `type modifiers` that affect validation of those values.
type Character {
name: String!
appearsIn: [Episode]!
}
# we're using a `String type` and marking it as `Non-Null` by adding an exclamation mark, `!` after the type name.
# The Non-Null type modifier can also be used when defining arguments for a field,
query DroidById($id: ID!) {
droid(id: $id) {
name
}
}
# We can use a `type modifier` to mark a type as a `List`, which indicates that this field will return an `array` of that type.
# In the schema language, this is denoted by wrapping the type in `square brackets`, [ and ].
# The Non-Null and List modifiers can be combined.
myField: [String!]
# This means that the list itself can be null, but it can't have any null members.
myField: null // valid
myField: [] // valid
myField: ['a', 'b'] // valid
myField: ['a', null, 'b'] // error
# defined a Non-Null List of Strings:
myField: [String]!
# This means that the list itself cannot be null, but it can contain null values:
myField: null // error
myField: [] // valid
myField: ['a', 'b'] // valid
myField: ['a', null, 'b'] // valid
# You can arbitrarily nest any number of Non-Null and List modifiers, according to your needs.
# 可以根据需要随意嵌套任意数量的非空和列表修饰符。
{
"data": {
"droid": null
}
}
{
"data": {
"droid": null
}
}
Interfaces
An
Interface
is an abstract type that includes a certain set of fields that a type must include to implement the interface.
interface Character {
id: ID!
name: String!
friends: [Character]
appearsIn: [Episode]!
}
# Star Wars trilogy 星球大战三部曲
# This means that any type that implements Character needs to have these exact fields, with these arguments and return types.
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
}
query HeroForEpisode($ep: Episode!) {
hero(episode: $ep) {
name
primaryFunction
}
}
query HeroForEpisode($ep: Episode!) {
hero(episode: $ep) {
name
... on Droid {
primaryFunction
}
}
}
{
"ep": "JEDI"
}
{
"errors": [
{
"message": `
Cannot query field \"primaryFunction\" on type \"Character\".
Did you mean to use an inline fragment on \"Droid\"?
`,
"locations": [
{
"line": 4,
"column": 5
}
]
}
]
}
{
"data": {
"hero": {
"name": "R2-D2",
"primaryFunction": "Astromech"
}
}
}
Union types
Union types
are very similar tointerfaces
, but they don't get to specify any common fields between the types
# Note that members of a union type need to be concrete object types;
# you can't create a union type out of interfaces or other unions.
union SearchResult = Human | Droid | Starship
{
search(text: "an") {
... on Human {
name
height
}
... on Droid {
name
primaryFunction
}
... on Starship {
name
length
}
}
}
{
search {
... on Human {
name
height
}
... on Droid {
name
primaryFunction
}
... on Starship {
name
length
}
}
}
{
"data": {
"search": [
{
"name": "Han Solo",
"height": 1.8
},
{
"name": "Leia Organa",
"height": 1.5
},
{
"name": "TIE Advanced x1",
"length": 9.2
}
]
}
}
{
"data": {
"search": [
{
"name": "Luke Skywalker",
"height": 1.72
},// Human
{
"name": "Darth Vader",
"height": 2.02
},
{
"name": "Han Solo",
"height": 1.8
},
{
"name": "Leia Organa",
"height": 1.5
},
{
"name": "Wilhuff Tarkin",
"height": 1.8
},
{
"name": "C-3PO",
"primaryFunction": "Protocol"
},// Droid
{
"name": "R2-D2",
"primaryFunction": "Astromech"
},
{
"name": "Millenium Falcon",
"length": 34.37
},
{
"name": "X-Wing",
"length": 12.5
},
{
"name": "TIE Advanced x1",
"length": 9.2
},// Starship
{
"name": "Imperial shuttle",
"length": 20
}
]
}
}
Introspection
http://graphql.org/learn/introspection/
Validation
http://graphql.org/learn/validation/
Execution
http://graphql.org/learn/execution/
BEST PRACTICES
GraphQL Best Practices
The GraphQL specification is intentionally silent on a handful of important issues facing APIs such as dealing with the network, authorization, and pagination.
http://graphql.org/learn/best-practices/
http://graphql.org/learn/thinking-in-graphs/
http://graphql.org/learn/serving-over-http/
http://graphql.org/learn/authorization/
http://graphql.org/learn/pagination/
http://graphql.org/learn/caching/
blog
©xgqfrms 2012-2025
www.cnblogs.com 发布文章使用:只允许注册用户才可以访问!
本文首发于博客园,作者:xgqfrms,原文链接:https://www.cnblogs.com/xgqfrms/p/7727983.html
未经授权禁止转载,违者必究!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· .NET10 - 预览版1新功能体验(一)
2015-10-25 python ( pycharm EDU)