- Основное использование
- Обзор GraphQL
- Основные возможности синтаксиса GraphQL
- Система типа GraphQL
- Основные типы, встроенные в систему типов GraphQL
- Встроенные модификаторы системы типа GraphQL
- Как работает GraphQL
- Процесс выполнения GraphQL
- Доступ проекта Vue к GraphQL
Основное использование (как его использовать)
package.json
"dependencies": {
"apollo-server-koa": "^1.3.6",
"graphql": "^0.13.2",
"graphql-import": "^0.6.0",
"graphql-tools": "^3.0.2",
"koa": "^2.5.1",
"koa-bodyparser": "^4.2.1",
"koa-router": "^7.4.0",
"koa-websocket": "^5.0.1"
},
"devDependencies": {
"babel-cli": "^6.26.0",
"babel-preset-env": "^1.7.0"
}
server.js
import koa from 'koa'
import koaRouter from 'koa-router'
import koaBody from 'koa-bodyparser'
import websocketify from 'koa-websocket'
import { graphqlKoa, graphiqlKoa } from 'apollo-server-koa'
import { makeExecutableSchema } from 'graphql-tools'
const app = websocketify(new koa())
const router = new koaRouter()
const PORT = 3000
// fake data
const moments = [
{
user: {
id: 1000,
name: '锐雯',
avatar: 'http://imgsrc.baidu.com/imgad/pic/item/42a98226cffc1e17d31927154090f603738de974.jpg'
},
main: {
content: '这是一条朋友圈',
pics: [
'https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1529219875063&di=bc0bcc78ae800c1c21c198f52697f515&imgtype=0&src=http%3A%2F%2Fimgsrc.baidu.com%2Fimgad%2Fpic%2Fitem%2F4a36acaf2edda3ccd53548ea0be93901203f9223.jpg',
'https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1529219893624&di=8d9e418df27e1fdb6afb1d993801a980&imgtype=0&src=http%3A%2F%2Fimgsrc.baidu.com%2Fimgad%2Fpic%2Fitem%2F3801213fb80e7beca9004ec5252eb9389b506b38.jpg'
]
},
comments: [
{
user: {
id: 233122,
name: '亚索'
},
reply: '面对疾风吧'
}
]
}
]
const typeDefs = `
type Query {
moments: [Moment]
}
type Mutation {
addComment(
entity: Add_Comment
) : Comment
}
type Moment {
user: User
main: Main
comments: [Comment]
}
type User {
id: Int
name: String
avatar: String
}
type Comment {
user: User
reply: String
}
type Main {
content: String
pics: [String]
}
input Add_User {
id: Int
name: String
}
input Add_Comment {
user: Add_User
reply: String
}
# 定义graphqlf服务哪个是RootQuery以及RootMutation
schema {
query: Query
mutation: Mutation
}
`
const resolvers = {
Query: {
moments () {
return moments
}
},
Mutation: {
addComment (_, { entity }, unknown, context) {
console.log(entity)
moments[0].comments.push(entity)
return entity
}
}
}
const schema = makeExecutableSchema({
typeDefs,
resolvers
})
// koaBody is needed just for POST.
router.post('/graphql', koaBody(), graphqlKoa({ schema: schema }))
// router.get('/graphql', graphqlKoa({ schema: schema }))
router.get('/graphiql', graphiqlKoa({ endpointURL: '/graphql' }))
async function responseMiddleware(ctx, next) {
ctx.set('Access-Control-Allow-Origin', 'http://localhost:8080')
ctx.set('Access-Control-Allow-Methods', 'POST,OPTIONS')
ctx.set('Access-Control-Allow-Headers', 'authorization,content-type')
// ctx.set('Access-Control-Allow-Credentials', 'true')
await next()
}
app.use(responseMiddleware)
app.use(router.routes())
app.use(router.allowedMethods())
app.ws.use(responseMiddleware)
app.ws.use(router.routes())
app.ws.use(router.allowedMethods())
app.listen(PORT)
Обзор GraphQL
Основные возможности синтаксиса GraphQL
Включая поля, псевдонимы, аргументы, фрагменты, переменные, директивы, встроенные фрагменты
- field
Система типа GraphQL
Схема GraphQL в основном состоит из двух типов записей RootQuery + RootMutation (операций) плюс RootValue (преобразователи). (здесь используются graphql-tools для определения всех типов в строке, которые позже будут перемещены в файл .graphql, а затем импортированы с помощью graphql-import)
Основные типы, встроенные в систему типов GraphQL
-
Скалярные типы
-
Int
: 32-битное целое число со знаком -
Float
: значение с плавающей запятой двойной точности со знаком -
String
: последовательность символов UTF-8 -
Boolean
: true or false -
ID
:ID Скалярный тип представляет собой уникальный идентификатор (похожий на UUID), обычно используемый для извлечения объектов или в качестве ключа в кэше. Тип ID сериализуется так же, как String.
-
-
Типы перечисления
это специальный скалярный тип
enum Episode {
NEWHOPE
EMPIRE
JEDI
}
- Типы массивов
с квадратными скобками[]
список тегов
- Типы интерфейсов
Это абстрактный тип, похожий на механизм интерфейса Java.
- Типы союзов
{
search(text: "an") {
... on Human {
name
height
}
... on Droid {
name
primaryFunction
}
... on Starship {
name
length
}
}
}
- Типы ввода
В отличие от всех типов, упомянутых ранее, это один и только один тип ввода, который в основном используется дляmutations
время доставки整个对象
случае он не имеет параметров.
Встроенные модификаторы
-
!
: означает не пустой. следующим образом
query DroidById($id: ID!) {
droid(id: $id) {
name
}
}
Как работает GraphQL
Каждое поле запроса в GraphQL — это функция супертипа, которая возвращает подтип. Каждому типу поля соответствуетresolver
Поддержка функции, когда поле выполняется, ответresolver
вызывается и возвращает результат.
Если поле выдает результат как标量类型
значение, такое как строка или число, выполнение завершено. иначе递归
Выполнять соответствующий парсер, пока результат не будет标量类型
стоимость.
Основной поток данных GraphQL
Верхний уровень каждого серверного приложения GraphQL должен иметь入口点
, обычно типа Root или Query, а затем выполнить предустановку поля解析器
(синхронный или асинхронный), а результат анализа каждого поля помещается в карту ключ-значение с именем поля (или псевдонимом) в качестве ключа и значением синтаксического анализатора в качестве значения, этот процесс начинается с поля запроса底部叶子节点
Начать возвращаться до тех пор, пока тип запроса起始节点
, и, наконец, сгенерировать镜像查询结果
вернуться к клиенту
Доступ проекта Vue к GraphQL
Установите vue-cli3.x
npm i -g @vue/cli
проект инициализации
vue create [project-name]
Внедрить плагин аполлона
cd [project-name]
vue add apollo
FriendCircle.vue
<template>
<div>
<div v-for="(item, index) in moments" :key="index">
{{item}}
</div>
<input type="text" v-model="comment.reply" placeholder="请输入要回复的内容">
<button @click="addComment">回复</button>
</div>
</template>
<script>
import gql from 'graphql-tag'
const QUERY_LIST = gql`
query {
moments {
user {
id
name
avatar
}
main {
content
pics
}
comments {
user {
id
name
}
reply
}
}
}
`
export default {
data () {
return {
moments: [],
comment: {
user: {
id: (Math.random() * 10000).toFixed(0),
name: '费德提克'
},
reply: ''
}
}
},
apollo: {
moments: {
query: QUERY_LIST
}
},
methods: {
addComment () {
this.$apollo.mutate({
mutation: gql`
mutation addComment($comment: Add_Comment) {
addComment(entity: $comment) {
user {
id
name
}
reply
}
}
`,
variables: {
comment: this.comment
},
update: (store, { data: { addComment } }) => {
// Read the data from our cache for this query.
const data = store.readQuery({ query: QUERY_LIST })
// set first moment's comment
data.moments[0].comments.push(addComment)
// Write our data back to the cache.
store.writeQuery({ query: QUERY_LIST, data })
}
})
}
}
}
</script>
Задействованными точками знаний являются Root_Query, Root_Mutation, переменные и кеш хранилища.
cache
Его основной механизм включает в себя следующие два пункта
- Кэширование всех (вложенных вложенных) некалярных типов, часто передавайте идентификатор типа или _ID и __typename уникальный идентификатор комбинации, затем хранить в плоской структуре данных
- Могут быть установлены различные стратегии кэширования: кэш-и-сеть, без кэша, только сеть.
обновить обратный вызов
В параметрах this.$apollo.mutate(options) есть обратный вызов обновления, который запускается после успешного ответа на данные и может быть напрямую прочитан и обработан с помощьюapollo-cache-inmemory
Сгенерированный магазин. В приведенном выше примере этот обратный вызов используется для синхронного обновления кеша и пользовательского интерфейса.
Примечание: все связанные переменные не могут быть изменены напрямую.Object.freeze используется внутри для замораживания объекта и не может быть добавлен или удален напрямую.