Первый тест Vue + GraphQL

Java внешний интерфейс GraphQL Vue.js
  • Основное использование
  • Обзор 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

Его основной механизм включает в себя следующие два пункта

  1. Кэширование всех (вложенных вложенных) некалярных типов, часто передавайте идентификатор типа или _ID и __typename уникальный идентификатор комбинации, затем хранить в плоской структуре данных
  2. Могут быть установлены различные стратегии кэширования: кэш-и-сеть, без кэша, только сеть.

обновить обратный вызов

В параметрах this.$apollo.mutate(options) есть обратный вызов обновления, который запускается после успешного ответа на данные и может быть напрямую прочитан и обработан с помощьюapollo-cache-inmemoryСгенерированный магазин. В приведенном выше примере этот обратный вызов используется для синхронного обновления кеша и пользовательского интерфейса.

Примечание: все связанные переменные не могут быть изменены напрямую.Object.freeze используется внутри для замораживания объекта и не может быть добавлен или удален напрямую.