После прочтения «Мстителей IV» я составил вводное руководство по GraphQL, ха-ха, оно действительно ароматное. . .
Добро пожаловать, чтобы следовать за мнойДомашняя страница && личный блог && личная база знаний&& Публичный аккаунт WeChat "Классы самообучения переднего плана"
Прежде всего, попросите Abba Town сделать публикацию! Ха-ха-ха, друзья, которым нужны оригинальные фотографии высокой четкости, могутНажмите на меня, чтобы скачать Abba Invincible.
Начнем эту статью:
1. Введение в GraphQL
GraphQL
разработано FacebookЯзык запросов для API, выпущенный публично в 2015 году, является заменой REST API.
GraphQL
оба APIязык запросовЭто также тот, который удовлетворяет ваш запрос данных.Время выполнения.GraphQL
Предоставляет полное и простое для понимания описание данных в вашем API, позволяя клиенту получить именно те данные, которые ему нужны, ибез избыточности, также облегчает развитие API с течением времени и может использоваться для создания мощных инструментов разработчика.
Официальный сайт:graphql.org/
Китайский сайт:graphql.cn/
1. Особенности
- Запросите данные, которые вы хотите, не больше и не меньше;
Такие как:hero
имеютname
, age
, sex
д., вы можете получить только те поля, которые вам нужны.
- Получите несколько ресурсов всего одним запросом;
типичныйREST API
Несколько URL-адресов должны быть загружены при запросе нескольких ресурсов, иGraphQL
Получите все данные, необходимые вашему приложению, одним запросом. Это также может гарантировать, что использование медленных подключений к мобильной сетиGraphQL
приложения также могут работать достаточно быстро.
- Опишите все возможные типы систем. Простое обслуживание, плавная эволюция в соответствии с требованиями, добавление или скрытие полей;
GraphQL
Использование типов гарантирует, что приложения запрашивают только возможные данные, а также предоставляет четкие вспомогательные сообщения об ошибках. Приложения могут использовать типы без написания кода для разбора вручную.
2. Простой случай
Давайте рассмотрим здесь простой случай и испытаем его.GraphQL
Магия (об этом позже).
Мы определяем оператор запроса следующим образом:
query {
hero
}
Тогда мы получим то, что ищемhero
Поле:
{
"data": {
"hero": "I'm iron man"
}
}
Так удобнее пользоваться?
2. Сравнение GraphQL и restful
1. Введение в отдых
Полное имя:Representational State Transfer
Переход состояния атрибута таблицы.
По сути, это определение uri и получение ресурсов через интерфейс API. Универсальная системная архитектура, не ограниченная языком.
Пример: Голодный интерфейс.
Например: интерфейсrestapi/shopping/v3/restaurants?latitude=13
является типичнымrestful
Интерфейс, определение ресурсов + условия запроса.
2. Сравнение с GraphQL
-
restful
Интерфейс может возвращать только один ресурс,GraphQL
Несколько ресурсов могут быть получены одновременно. -
restful
Используйте разные URL-адреса, чтобы различать ресурсы,GraphQL
Различать ресурсы по типу.
3. Используйте экспресс для создания базового приветственного мира
1. Простой случай
Сначала создайте папкуdemo
и инициализироватьpackage.json
,Установитьexpress
/ graphql
/ express-graphql
Пакет зависимостей:
npm init -y
npm install express graphql express-graphql -S
создать новыйhello.js
, импортируйте файл:
const express = require('express')
const { buildSchema } = require('graphql')
const graphqlHTTP = require('express-graphql')
Создаватьschema
для определения операторов и типов запросов,buildSchema()
Параметры, которые должен передать метод:нитьтип, например следующийhero
поле запроса, за которым следуетString
Тип указывает тип данных, возвращаемый полем:
const schema = buildSchema(`
type Query {
hero: String
}
`)
Создаватьroot
Процессор, который обрабатывает соответствующий запрос, здесьhello
Процессор соответствуетschema
серединаhero
Обработка запроса поля, возврат прямо сюдаI'm iron man
результат:
const root = {
hero: () => {
return "I'm iron man"
}
}
Конечно, в процессоре могут быть и другие сложные операции, которые будут представлены позже.
затем создайте экземплярexpress
, и перенаправить маршрут наgraphqlHTTP
иметь дело с:
const app = express()
app.use('/graphql', graphqlHTTP({
schema,
rootValue: root,
graphiql: true
}))
app.listen(3000)
graphqlHTTP
Три параметра во введении:
-
schema
: Определенные операторы запроса и типы -
rootValue
: Процессор, который обрабатывает соответствующий запрос -
graphiql
: открывать ли окно отладки, открывать на стадии разработки, закрывать на стадии производства
Затем запустите проект и выполните его в командной строке.node hello.js
, который можно найти здесьgraphiql
Сделай отладку, открой адресlocalhost:3000/graphiql
Вы можете запросить счастливо.
Дополнительно мы можемgraphiql
Открыть в правой части интерфейсаDocsПросмотрите все поля и описания, которые мы определили.
Окончательный код:
const express = require('express')
const { buildSchema } = require('graphql')
const graphqlHTTP = require('express-graphql')
// 构建schema,这里定义查询的语句和类型
const schema = buildSchema(`
type Query {
hero: String
}
`)
// 定义查询所对应的 resolver,也就是查询对应的处理器
const root = {
hero: () => {
return "I'm iron man"
}
}
const app = express()
// 将路由转发给 graphqlHTTP 处理
app.use('/graphql', graphqlHTTP({
schema: schema,
rootValue: root,
graphiql: true
}))
app.listen(3000)
2. Пользовательский тип запроса
В нашем предыдущем запросе мы имеемhero
Поле определяется какString
тип, но часто в разработке мы будем сталкиваться с полями с несколькими типами, т.е.Поля также могут ссылаться на типы объектов (Object), напримерuser
поле будет иметьname
,age
поля etc, в то время какname
тип возвращаемой строки,age
Возвращает числовой тип.
В этот момент мы можем выполнитьподвыбор. Запросы GraphQL могут перемещаться по связанным объектам и их полям, что позволяет клиентам запрашивать большие объемы связанных данных в одном запросе вместо нескольких круговых обходов, как в традиционных архитектурах REST.
Мы можем создать новый тип запроса для определенияuser
Тип, возвращаемый полем:
const schema = buildSchema(`
type User {
# 查询可以有备注!
name: String
age: Int
}
type Query {
hero: String
user: User
}
`)
В процессоре также добавляем:
const root = {
hero: () => {
return "I'm iron man"
},
user: () => {
return {
name: 'leo',
age: 18
}
}
}
Проблема типа параметра Int/String здесь будет рассмотрена в следующей главе.
В-четвертых, типы параметров и передача параметров
1. Основные типы параметров
String
, Int
, Float
, Boolean
а такжеID
, эти основные типы параметров можно найти вschema
используется непосредственно в заявлении.
-
Int
: 32-битное целое число со знаком. -
Float
: Значение двойной точности с плавающей запятой со знаком. -
String
:UTF‐8
последовательность символов. -
Boolean
:true
илиfalse
. -
ID
:ID
Скалярный тип представляетуникальный идентификатор, обычно используемый для извлечения объекта или в качестве ключа в кэше.ID
использование типа иString
сериализовать таким же образом, однако определить его какID
средства иУдобочитаемый тип не требуется.
В качестве альтернативы мы можем использовать[类型]
для представления класса массивов, например:
-
[Int]
Представляет массив целых чисел; -
[String]
Представляет массив строк;
2. Передача параметров
Использование такое же, как и при передаче параметров JS, формальные параметры определены в круглых скобках, ноПараметр должен определять тип.
использовать!
Указывает, что параметр не может быть пустым.
Следующий случай: параметрteamName
даString
тип, который необходимо передать, при этомnumber
параметры такжеInt
Типа, но его передавать не требуется, а конечный вывод тожеString
Типы.
type Query {
getHero(teamName: String!, number: Int): [String]
}
Следующий случай:
//...省略其他
const schema = buildSchema(`
type Query {
getHero(teamName: String!): [String]
}
`)
const root = {
getHero: ({teamName}) => {
// 这里的操作 实际开发中常常用在请求数据库
const hero = {
'三国': ['张飞', '刘备', '关羽'],
'复仇者联盟': ['钢铁侠', '美国队长', '绿巨人']
}
return hero[teamName]
}
}
//...省略其他
В это время мыGraphiQLВведите запрос наМстителистатистика героя.
// 查询
query {
getHero(teamName:"复仇者联盟")
}
// 结果
{
"data": {
"getHero": [
"钢铁侠",
"美国队长",
"绿巨人"
]
}
}
3. Пользовательский тип возврата
В реальной разработке тип данных, который мы возвращаем, может быть объектом, и объект может иметь какInt
свойства типа, есть такжеString
значение типа и т. д., здесь мы можем использоватьнастраиваемый тип возвратаобрабатывать:
//...省略其他
const schema = buildSchema(`
type Hero {
name: String
age: Int
doSomething(thing: String): String
}
type Query {
getSuperHero(heroName: String!): Hero
}
`)
const root = {
getSuperHero: ({heroName}) => {
// 这里的操作 实际开发中常常用在请求数据库
const name = heroName
const age = 18
const doSomething = ({thing}) => {
return `I'm ${name}, I'm ${thing} now`
}
return { name, age, doSomething }
}
}
//...省略其他
указано здесьgetSuperHero
Тип возвращаемого значения поляHero
тип, который затем определяется вышеHero
.
вHero
типdoSomething
Также можно передать указанный параметр типа и указать возвращаемый тип.
Взгляните на вывод ниже:
// 查询
query {
getSuperHero(heroName:"IronMan") {
name
age
doSomething
}
}
// 结果
{
"data": {
"getSuperHero": {
"name": "IronMan",
"age": 46,
"doSomething": "I'm IronMan, I'm undefined now"
}
}
}
Здесь вы также можете датьdoSomething
Передавая параметры, вы получите разные результаты:
// 查询
query {
getSuperHero(heroName:"IronMan") {
name
age
doSomething(thing:"watching TV")
}
}
// 结果
{
"data": {
"getSuperHero": {
"name": "IronMan",
"age": 46,
"doSomething": "I'm IronMan, I'm watching TV now"
}
}
}
5. Клиент GraphQL
В этом разделе мы узнаем, как получить доступ в клиентеgraphql
Интерфейс.
1. Внутренний интерфейс определения
Сначала мы завершаем разработку интерфейса на бэкенде, который похож на предыдущий, но требует еще одного шага, используяexpress
Откройте папку извне, чтобы пользователи могли получить доступ к статическим файлам ресурсов:
Используйте код из предыдущего раздела прямо здесь~
// index.js 开发 graphql 接口
//...省略其他
const schema = buildSchema(`
type Hero {
name: String
age: Int
doSomething(thing: String): String
}
type Query {
getSuperHero(heroName: String!): Hero
}
`)
const root = {
getSuperHero: ({heroName}) => {
// 这里的操作 实际开发中常常用在请求数据库
const name = heroName
const age = 46
const doSomething = ({thing}) => {
return `I'm ${name}, I'm ${thing} now`
}
return { name, age, doSomething }
}
}
const app = express()
app.use('/graphql', graphqlHTTP({
schema, rootValue: root, graphiql: true
}))
// 公开文件夹 使用户访问静态资源
app.use(express.static('public'))
app.listen(3000)
Таким образом, мы предоставляем интерфейсной странице функцию, которая может обращаться к статическим ресурсам.
Здесь также необходимо создатьpublicпапку, а в папку добавитьindex.html
файл, структура каталогов на данный момент:
|-node_modules
|-public
|---index.html
|-index.js
|-package.json
2. Запрос страницы интерфейса
тогда дайindex.html
Добавьте привязки кнопок и событий:
переменная здесьquery
ЯвляетсяТип строкиопределить состояние запроса, в состоянииGetSuperHero
параметры в , вам нужно использовать$
символы для идентификации и в фактическом запросеgetSuperHero
, тип параметра задается как параметр.
затем определите переменнуюvariables
, указав значение свойства, за которым следуетfetch
Обратиться с просьбой:
<button onclick="getData()">获取数据</button>
<script>
function getData(){
const query = `
query GetSuperHero($heroName: String, $thing: String){
getSuperHero(heroName: $heroName){
name
age
doSomething(thing: $thing)
}
}
`
// 如果不需要其他参数 至少要传一个参数 否则会报错
// const query = `
// query GetSuperHero($heroName: String){
// getSuperHero(heroName: $heroName){
// name
// }
// }
// `
const variables = {heroName: '钢铁侠', thing: 'watching TV'}
fetch('./graphql', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json'
},
body: JSON.stringify({
query, variables
})
})
.then(res => res.json())
.then(json => {
console.log(json)
})
}
</script>
Когда мы закончим писать, нажмитеполучить данныеНа консоль будут выведены следующие данные:
{
"data":{
"getSuperHero":{
"name":"钢铁侠",
"age":46,
"doSomething": "I'm 钢铁侠, I'm watching TV now"
}
}
}
3. На заметку
- в запросе
query
Параметры нужно хорошо сравнивать$
Символьные переменные.
проверить предложениеquery GetSuperHero($heroName: String)
параметры$heroName
серединаheroName
;
проверить предложениеgetSuperHero(heroName: $heroName)
тип$heroName
серединаheroName
;
Переменнаяvariables
серединаheroName
Атрибуты;
Три имени должны быть одинаковыми.
- данные нужны в запросеоперация сериализации.
body: JSON.stringify({ query, variables })
6. Используйте мутации для изменения данных
1. Использование мутаций
Согласно предыдущему исследованию, мы знаем, что для выполнения операции запроса нам нужно использоватьQuery
объявить:
type Query {
queryHero(heroName: String): String
}
когда мы делаемИзменить операцию, вам нужно использоватьMutation
:
type Mutation {
createHero(heroName: String): String
}
еслиMutation
Формальные параметры полей впользовательский тип, то тип должен использоватьinput
Я БЫ:
const schema = buildSchema(`
# 输入类型 用 input 标识
input HeroInput {
name: String
age: Int
}
# 查询类型
type Hero {
name: String
age: Int
}
type Mutation {
createHero(heroName: String): Hero
updateHero(heroName: String, hero: HeroInput): Hero
}
`)
Примечание. Здесь вам необходимо определить хотя бы одинQuery
иначеGraphiQL
Запрос не будет отображаться:
type Query {
hero: [Hero]
}
2. Варианты использования мутации
сначала создайтеschema
, содержимое — это содержимое, определенное на предыдущем шаге [1. Использование мутации], которое здесь повторяться не будет.
Затем смоделируйте создание локальной базы данныхlocalDb
, используемый для имитации хранения добавленных данных супергероя:
const localDb = {}
Следующее заявлениеroot
выполнитьschema
Полевые методы в:
const root = {
hero() {
// 这里需要转成数组 因为前面定义了返回值是 [Hero] 类型
let arr = []
for(const key in localDb){
arr.push(localDb[key])
}
return arr
},
createHero({ input }) {
// 相当于数据库的添加操作
localDb[input.name] = input
return localDb[input.name]
},
updateHero({ id, input }) {
// 相当于数据库的更新操作
const update = Object.assign({}, localDb[id], input)
localDb[id] = update
return update
}
}
окончательная конфигурацияgraphqlHTTP
Способ и запуск сервера здесь повторяться не будем.
Окончательный код:
//...省略其他
const schema = buildSchema(`
# 输入类型 用 input 标识
input HeroInput {
name: String
age: Int
}
# 查询类型
type Hero {
name: String
age: Int
}
type Mutation {
createHero(input: HeroInput): Hero
updateHero(id: ID!, input: HeroInput): Hero
}
# 需要至少定义一个 Query 不要GraphiQL会不显示查询
type Query {
hero: [Hero]
}
`)
const localDb = {}
const root = {
hero() {
// 这里需要转成数组 因为前面定义了返回值是 [Hero] 类型
let arr = []
for(const key in localDb){
arr.push(localDb[key])
}
return arr
},
createHero({ input }) {
// 相当于数据库的添加操作
localDb[input.name] = input
return localDb[input.name]
},
updateHero({ id, input }) {
// 相当于数据库的更新操作
const update = Object.assign({}, localDb[id], input)
localDb[id] = update
return update
}
}
//...省略其他
Теперь мы можем запустить сервер, вGraphiQL
Проверьте эффект.
мы используемmutation
изcreateHero
Поле добавляет две части данных:
mutation {
createHero(input: {
name: "钢铁侠"
age: 40
}){
name
age
}
}
mutation {
createHero(input: {
name: "美国队长"
age: 41
}){
name
age
}
}
затем используйтеquery
изhero
Полевой запрос добавил результаты:
query {
hero {
name
age
}
}
Таким образом, мы получаем результат сложения только что:
{
"data": {
"hero": [
{
"name": "钢铁侠",
"age": 40
},
{
"name": "美国队长",
"age": 41
}
]
}
}
Затем мы начинаем обновлять данные, используяmutation
изupdateHero
поле будетКапитан Америкаизage
Измените значение на 18:
mutation {
updateHero(id: "美国队长", input: {
age: 18
}){
age
}
}
повторное использованиеquery
изhero
Поле запроса новых данных, вы найдетеКапитан Америкаизage
Значение было обновлено до 18:
{
"data": {
"hero": [
{
"name": "钢铁侠",
"age": 40
},
{
"name": "美国队长",
"age": 18
}
]
}
}
7. Аутентификация и промежуточное ПО
Мы знаем, что интерфейс для изменения данных не может быть свободно доступен всем, поэтому необходимо добавить аутентификацию по разрешениям, чтобы люди с разрешениями могли получить к нему доступ.
существуетexpress
, Это легко использоватьпромежуточное ПОЧтобы перехватить запрос, отфильтруйте запрос без разрешения и верните сообщение об ошибке.
Middleware на самом деле является функцией, которая перехватывает запрос до того, как интерфейс будет выполнен, а затем решает, продолжать ли нам опускаться или возвращать сообщение об ошибке.
Это в окончательном коде [Six, использование мутаций для изменения данных], добавление этого промежуточного программного обеспечения:
//... 省略其他
const app = express()
const middleWare = (req, res, next) => {
// 这里是简单模拟权限
// 实际开发中 更多的是和后端进行 token 交换来判断权限
if(req.url.indexOf('/graphql') !== -1 && req.headers.cookie.indexOf('auth') === -1){
// 向客户端返回一个错误信息
res.send(JSON.stringify({
err: '暂无权限'
}))
return
}
next() // 正常下一步
}
// 注册中间件
app.use(middleWare)
//... 省略其他
Принятие решения о разрешении здесь является простой симуляцией.token
Exchange для определения разрешений (или других форм).
Перезапускаем сервер, открываемhttp://localhost:3000/graphql
, обнаружил, что страница выдает ошибку, потому чтоcookies
не содержитauth
нить.
Если будет предложено здесьTypeError: Cannot read property 'indexOf' of undefined
, вы можете оставить его в покое, потому что браузер неcookies
Фактически, предыдущую логику оценки разрешений необходимо оценивать в соответствии с конкретными бизнес-сценариями.
Для удобства тестирования мы в консоли браузера хромapplication
, установить вручнуюauth
одна из строкcookies
, только для пробного использования.
После завершения настройки мы можем войти на страницу в обычном режиме.
Восемь, ConstructingTypes
В предыдущем введении мы собирались создатьschema
оба используютbuildSchema
метод для определения, но мы также можем использовать другой способ определения.
Это конструктор, чтобы научиться использовать здесьgraphql.GraphQLObjectType
Определение, он имеет ряд преимуществ и недостатков:
- преимущество: Уведомления об ошибках стали более интуитивно понятными, структура стала понятнее, а обслуживание стало проще.
- недостаток: количество кода увеличивается.
1. Определите тип
Здесь определено ранееHero
Введите для преобразования:
const graphql = require('graphql') // 需要引入
const HeroType = new graphql.GraphQLObjectType({
name: 'Hero',
fields: {
name:{ type: graphql.GraphQLString },
age:{ type: graphql.GraphQLInt },
}
})
Разница между ними заключается в следующем:
разница | buildSchema |
graphql.GraphQLObjectType |
---|---|---|
Тип параметра | нить | объект |
имя класса | следитьtype после символов вотtype Hero
|
в объекте параметраname атрибут |
определение свойства | Определяется после типа,пара ключ-значениеформа | определено в объекте параметраfields В атрибуте значение является объектом, каждое имя атрибута является именем ключа, а значение также является объектом, гдеtype Стоимость имуществаgraphql свойства в , которые будут добавлены ниже |
Пополнить:
fields
Типы подсвойств в свойствах обычно следующие:
graphql.GraphQLString
graphql.GraphQLInt
-
graphql.GraphQLBoolean
....
то естьGraphQL
Далее следует имя базового типа.
2. Определите запрос
При определении запроса он аналогичен предыдущему.Для понимания можно обратиться к следующей сравнительной диаграмме.Разница здесь в том, что здесь большеresolve
метод, этот метод используется для выполнения логики обработки запроса, который фактически является предыдущимroot
метод в .
const QueryType = new graphql.GraphQLObjectType({
name: 'Query',
fields: {
// 一个个查询方法
getSuperHero: {
type: HeroType,
args: {
heroName: { type: graphql.GraphQLString }
},
// 方法实现 查询的处理函数
resolve: function(_, { heroName }){
const name = heroName
const age = 18
return { name, age }
}
}
}
})
3. Создайте схему
При создании просто создайте экземпляр и передайте параметры:
// step3 构造 schema
const schema = new graphql.GraphQLSchema({ query: QueryType})
Окончательное использование такое же, как и раньше:
const app = express()
app.use('/graphql', graphqlHTTP({
schema,
graphiql: true
}))
app.listen(3000)
9. Борьба с базой данных
Давайте попробуем разработать простой практический проект, используя то, что мы узнали ранее:
пройти черезGraphiQL
страница, чтобыMongodb
Вставляйте и обновляйте данные в , в основном используйте операции, описанные в главе [6. Изменение данных с помощью мутаций].
1. Создайте и запустите локальную базу данных MongoDB.
Сначала мы можем пойти вофициальный сайт монгодбВыберите соответствующую платформу и версию для загрузки и установки.
Загрузите и установите шаги, вы можете обратиться кзагрузка, установка и настройка mongoDB, я не буду вводить здесь больше~~
После завершения установки мы открываем два терминала и выполняем следующие две строки команд:
// 终端1 启动数据库
mongod --dbpath c:\leo\app\mongodb\data\db
// 终端2 进入数据库命令行操作模式
mongo
2. Подключитесь к базе данных, создайте схему и модель
Сначала мы создаем новый файлdb.js
,а такжеnpm install mongoose
Установитьmongoose
, а затем напишите следующий код для достиженияПодключиться к базе данных:
const express = require('express')
const { buildSchema } = require('graphql')
const graphqlHTTP = require('express-graphql')
const mongoose = require('mongoose')
const DB_PATH = 'mongodb://127.0.0.1:27017/hero_table'
const connect = () => {
// 连接数据库
mongoose.connect(DB_PATH)
// 连接断开
mongoose.connection.on('disconnected', () => {
mongoose.connect(DB_PATH)
})
// 连接失败
mongoose.connection.on('error', err => {
console.error(err)
})
// 连接成功
mongoose.connection.on('connected', async () => {
console.log('Connected to MongoDB connected', DB_PATH)
})
}
connect()
затем создайтеSchema
а такжеModel
:
let HeroSchema = new mongoose.Schema({
name: String,
age: Number
})
let HeroModel = mongoose.model('hero',HeroSchema, 'hero_table')
3. Объявите оператор запроса
На этом шаге сначала используйте логику работы из главы [6. Использование мутаций для изменения данных], то есть сначала используйтеЗапрос на создание строки, Вместо того, чтобы использоватьGraphQLObjectType
Создайте:
const schema = buildSchema(`
# 输入类型 用 input 标识
input HeroInput {
name: String
age: Int
}
# 查询类型
type Hero {
name: String
age: Int
}
type Mutation {
createHero(input: HeroInput): Hero
updateHero(hero: String!, input: HeroInput): Hero
}
# 需要至少定义一个 Query 不要GraphiQL会不显示查询
type Query {
hero: [Hero]
}
`)
Тут дело немного изменено
4. Реализуйте логику для добавления данных и обновления данных
Чтобы разобраться с логикой добавления данных и обновления данных здесь необходимо модифицировать ранее объявленныйroot
Содержание операции:
const root = {
hero() {
return new Promise( (resolve, reject) => {
HeroModel.find((err, res) => {
if(err) {
reject(err)
return
}
resolve(res)
})
})
},
createHero({ input }) {
// 实例化一个Model
const { name, age } = input
const params = new HeroModel({ name, age })
return new Promise( (resolve, reject) => {
params.save((err, res) => {
if(err) {
reject(err)
return
}
resolve(res)
})
})
},
updateHero({ hero, input }) {
const { age } = input
return new Promise ((resolve, reject) => {
HeroModel.update({name: hero}, {age}, (err, res) => {
if(err) {
reject(err)
return
}
resolve(res)
})
})
}
}
5. Пробный тест
Наконец мыGraphiQL
Чтобы протестировать симуляцию на странице, сначала добавьте двух героев, Железного человека и Капитана Америку, и установите ихage / name
Атрибуты:
mutation {
createHero(input: {
name: "钢铁侠"
age: 40
}){
name
age
}
}
mutation {
createHero(input: {
name: "美国队长"
age: 20
}){
name
age
}
}
На странице и в интерфейсе не сообщается об ошибке, что указывает на то, что мы успешно добавили, и в базе данных также есть эти два данных:
Тестируемый запрос:
query {
hero {
name
age
}
}
Запрос тоже нормальный.Далее обновите тест и обновите Капитана Америкуage
Модифицировано до 60:
mutation {
updateHero(hero: "美国队长", input: {
age: 60
}){
age
}
}
На этом мы закончили упражнение.
Суммировать
-
GraphQL
этоЯзык запросов для API, замена REST API. -
GraphQL
Вы можете использовать один запрос, чтобы получить все данные, которые вы хотите. -
Есть два способа создать запрос: использовать
buildSchema
илиGraphQLObjectType
. -
Для операции запроса
Query
, для изменения операцииMutations
. -
тип запроса
type
, тип ввода сinput
.
фактическиGraphQL
Он по-прежнему очень прост и удобен в использовании~~~
Эта статья была впервые опубликована вpingan8787 личный блог, если вам нужно перепечатать, пожалуйста, оставьте свое личное представление