[译] 怎样使用GraphQL - 3.核心概念

英文原版地址:https://www.howtographql.com/...javascript

在本章中,你将了解GraphQL的一些基本语言结构。 内容包括,初次认识,定义类型,查询和mutation的语法。咱们还为你准备了一个基于graphql-up的沙箱环境,你可使用它来实验学到的内容。java

视图定义语言(SDL)

GraphQL有本身的类型系统,用于定义API的Schema。编写Schema的语法称为SDL。git

如下是使用SDL定义简单类型Person的示例:github

type Person {
  name: String!
  age: Int!
}

这个Person类型有两个字段,nameage,是String和Int类型的,紧跟着的 ! 表示该字段是必需的。数据库

能够在类型之间相互使用。在博客应用的例子中,一个Person能够与一个Post相关联:后端

type Post {
  title: String!
  author: Person!
}

同时,另外一方面,Person类型中添加相应类型。数组

type Person {
  name: String!
  age: Int!
  posts: [Post!]!
}

请注意,咱们刚刚建立了PersonPost之间的一对多关系,由于Person上的posts字段其实是一个帖子数组。服务器

使用查询语句获取数据

使用REST API时,会从指定接口加载数据。每一个接口都明肯定义了返回的数据结构。这意味着客户端须要的数据,已经在URL中制定好了。数据结构

GraphQL中采用的方式大相径庭。GraphQL的API一般只暴露一个接口,而不是返回固定数据结构的多个接口。 这是由于返回的数据结构不是一成不变的,而是灵活的,让客户端来决定真正须要的是什么数据。post

这意味着客户端须要向服务端发送更多信息来告知所需求的数据 - 这个额外信息称为查询。

基本查询

咱们来看看客户端发送给服务端的简单查询示例:

{
  allPersons {
    name
  }
}

在这查询中,allPersons字段称为查询的根字段。根字段以后的全部内容称为查询的payload。此查询中,指定的惟一payload字段是name

此查询将返回当前存储在数据库中的全部的人员列表。返回的示例以下:

{
  "allPersons": [
    { "name": "Johnny" },
    { "name": "Sarah" },
    { "name": "Alice" }
  ]
}

请注意,每一个Person在响应结果中只有name一个属性,服务端并无返回age属性。 这正是由于name是在查询中指定的惟一字段。

若是客户端也想要获取年龄属性,那么要作的,仅仅是调整一下查询语句,在查询的payload中加入新的字段:

{
  allPersons {
    name
    age
  }
}

GraphQL的一个重要优点是,容许直接经过嵌套的方式查询信息。例如,若是想获取一个Person写的全部posts,能够简单地按照类型的结构来获取数据:

{
  allPersons {
    name
    age
    posts {
      title
    }
  }
}

查询时带上参数

在GraphQL中,每一个在视图中定义的字段均可以拥有参数(零或多个)。例如,allPersons字段能够包含last参数,用来返回特定数量的Persons。相应的查询以下:

{
  allPersons(last: 2) {
    name
  }
}

经过Mutation操做数据

在从服务端获取到数据以后,主流的应用程序老是要更改存储在后端的数据。使用GraphQL,这些更改是使用Mutation来完成的。 Mutation通常有这三种:

  • 建立新数据

  • 更新现有数据

  • 删除现有数据

Mutation遵循与查询相同的语法结构,可是它们始终须要从Mutation关键字开始。 如下是咱们如何建立一个新的Person的例子:

mutation {
  createPerson(name: "Bob", age: 36) {
    name
    age
  }
}

请注意,与以前写的查询相似,mutation也有一个根字段,上面的例子中,这个字段是createPerson。 咱们以前已经讲到过关于查询参数的内容。例子中,createPerson接受nameage两个参数。

像查询同样,咱们还能够为mutation指定一个payload,咱们能够在其中请求新建的Person对象的其余属性。 在咱们的例子中,咱们指定的是nameage,虽然咱们的例子并非颇有意义,由于咱们获取的是咱们已知的数据。但咱们已经清晰的了解到,当请求是mutation时,也可以指定查询信息,这体现了mutation的强大之处,容许在一次请求来回中,从服务器获取新数据!

上面的mutation的响应数据是这样的:

"createPerson": {
  "name": "Bob",
  "age": "36",
}

咱们老是能了解到,当新增数据时,GraphQL会在服务端生成一个惟一的ID类型。扩展一下咱们以前定义的Person类型,咱们能够添加一个id字段,以下所示:

type Person {
  id: ID!
  name: String!
  age: Int!
}

如今,当建立一个新的Person时,能够直接在mutation的payload中查询id,这是事先在客户端不知道的信息:

mutation {
  createPerson(name: "Alice", age: 36) {
    id
  }
}

使用Subscription进行实时更新

今天,许多应用的另外一个重要需求是与服务端进行实时链接,以便实时响应重要事件。针对这种场景,GraphQL提供了订阅的概念。

当客户端订阅了事件,它将与服务器创建一个稳定链接并保持住这个连接。任什么时候刻,当有事件触发时,服务端都会把相关信息推送到客户端。不一样于查询和mutation,订阅表明的是将数据推送出去的的模式,而不是经典的“请求 - 响应”的模式。

订阅使用的语法和查询和mutation相同。咱们用来订阅Person类型上的事件,以下所示:

subscription {
  newPerson {
    name
    age
  }
}

在客户端将此订阅发送到服务端以后,会创建起一个连接。以后,每当mutation被执,用来建立新的Person时,服务端就会把有关此人的信息发送给客户端:

{
  "newPerson": {
    "name": "Jane",
    "age": 23
  }
}

定义视图(Schema)

如今,你已经对查询,mutation和订阅有一个基本的了解,让咱们将这些放在一块儿,学习如何编写一个视图,让你本身执行目前为止全部的示例。

视图是使用GraphQL API时最重要的概念之一。它指定了API的功能,并定义了客户端如何请求数据。它一般被视为服务器和客户端之间的协议。

一般,视图只是GraphQL类型的集合。 可是,在为API编写视图时,有一些特殊的根类型:

type Query { ... }
type Mutation { ... }
type Subscription { ... }

查询,mutation和订阅是客户端发送请求的入口点。要启用咱们前面看到的allPersons查询,查询类型必须以下定义:

type Query {
  allPersons: [Person!]!
}

allPersons称为API的根字段。再考虑到,咱们将last参数添加到allPersons的示例,咱们必须以下定义Query:

type Query {
  allPersons(last: Int): [Person!]!
}

相似地,对于createPersonmutation,咱们必须向Mutation类型添加一个根字段:

type Mutation {
  createPerson(name: String!, age: String!): Person!
}

请注意,根字段有两个参数,Person的nameage

最后,对于订阅,咱们必须添加newPerson根字段:

type Subscription {
  newPerson: Person!
}

将全部整合在一块儿,这是你在本章中看到的全部查询和mutation的完整模式:

type Query {
  allPersons(last: Int): [Person!]!
}

type Mutation {
  createPerson(name: String!, age: String!): Person!
}

type Subscription {
  newPerson: Person!
}

type Person {
  name: String!
  age: Int!
  posts: [Post!]!
}

type Post {
  title: String!
  author: Person!
}
相关文章
相关标签/搜索