SDL
GraphQL SDL
SDL(Schema Definition Language)是标准的

Node 中的Schema 对象
GraphQLSchema 对象
const { graphql, buildSchema } = require("graphql");
// 使用 GraphQL schema language 定义 Schema
const schema = buildSchema(`
type Query {
hello: String
}
`);
// 为每个 API 端点提供解析函数
const root = {
hello: () => {
return "Hello world!";
}
};
// 执行查询请求,并且获取结果
graphql(schema, "{ hello }", root).then(response => {
console.log(response);
});
另一种常见的
const {
GraphQLObjectType,
GraphQLSchema,
GraphQLNonNull,
GraphQLInt
} = require("graphql");
const queryType = new GraphQLObjectType({
name: "Query",
fields: {
posts: {
type: postType
},
author: {
name: "author",
type: authorType,
arguments: { id: { type: new GraphQLNonNull(GraphQLInt) } }
}
}
});
// ... postType and authorType defined similarly
const schema = new GraphQLSchema({
query: queryType
});
Apollo GraphQL
import gql from "graphql-tag";
const query = gql`
{
user(id: 5) {
firstName
lastName
}
}
`;
// query is now a GraphQL syntax tree object
console.log(query);
// {
// "kind": "Document",
// "definitions": [
// {
// "kind": "OperationDefinition",
// "operation": "query",
// "name": null,
graphql-tools 则提供了完整的
import { buildSchema, printSchema, makeExecutableSchema } from "graphql-tools";
const sdlSchema = `...`;
// 仅仅生成 Schema 对象
const graphqlSchemaObj = buildSchema(sdlSchema);
// 生成可用于服务端的 Schema 对象
const graphqlSchemaObj = makeExecutableSchema({
typeDefs: sdlSchema,
resolvers: {
Query: {
author: () => ({ firstName: "Ada", lastName: "Lovelace" })
}
}
});
// 转化为 SDL
console.log(printSchema(graphqlSchemaObj));
类型基础
类型声明
type
关键字来指定类型名,类型还可以继承一到多个接口:
type Post implements Item {
# ...
}
某个属性域包含了名称与类型,该类型可以是内建或自定义的标量类型,也可以是!
来标记:
age: Int!
较为全面的类型定义范例如下:
type Post {
id: String!
title: String!
publishedAt: DateTime!
likes: Int! @default(value: 0)
blog: Blog @relation(name: "Posts")
}
type Blog {
id: String!
name: String!
description: String
posts: [Post!]! @relation(name: "Posts")
}
内省查询结果
__schema
端口的返回结果:
{
__schema {
types {
kind
name
possibleTypes {
name
}
}
}
}
我们可以利用
const { introspectionQuery } = require("graphql");
// ...
fetch("https://1jzxrj179.lp.gql.zone/graphql", {
// ...
body: JSON.stringify({ query: introspectionQuery })
});
// ...
同样的,我们可以将内省的查询结果转化为
const { buildClientSchema } = require("graphql");
const fs = require("fs");
const introspectionSchemaResult = JSON.parse(fs.readFileSync("result.json"));
const graphqlSchemaObj = buildClientSchema(introspectionSchemaResult);
Scalar Type | 标量类型
- Int
- Float
- String
- Boolean
- ID
enum Category {
PROGRAMMING_LANGUAGES
API_DESIGN
}
自定义标量类型
import { makeExecutableSchema } from "graphql-tools";
import GraphQLJSON from "graphql-type-json";
const schemaString = `
scalar JSON
type Foo {
aField: JSON
}
type Query {
foo: Foo
}
`;
const resolveFunctions = {
JSON: GraphQLJSON
};
const jsSchema = makeExecutableSchema({
typeDefs: schemaString,
resolvers: resolveFunctions
});
Object Type | 对象类型
数组则是用大括号表示:
names: [String!]
Type Modifier | 类型修饰
Interface | 接口
在interface
是一系列属性域的集合。
Directive | 指令
我们可以通过指令来为任意的
name: String! @defaultValue(value: "new blogpost")
directive @deprecated(
reason: String = "No longer supported"
) on FIELD_DEFINITION | ENUM_VALUE
type ExampleType {
newField: String
oldField: String @deprecated(reason: "Use `newField`.")
}
在实际开发中,我们可以使用
import { SchemaDirectiveVisitor } from "graphql-tools";
class DeprecatedDirective extends SchemaDirectiveVisitor {
public visitFieldDefinition(field: GraphQLField<any, any>) {
field.isDeprecated = true;
field.deprecationReason = this.args.reason;
}
public visitEnumValue(value: GraphQLEnumValue) {
value.isDeprecated = true;
value.deprecationReason = this.args.reason;
}
}
然后在声明
Fragments
recentPost {
title
description
author {
...authorInfo
}
}
fragment authorInfo as Author {
id
name
}
Query & Mutation | 查询与更改
type Query {}
type Mutation {}
type Subscription {}
schema {
query: Query
mutation: Mutation
subscription: Subscription
}