graphql新手包
GraphQl
GraphQL
是一个旨在简化前端和后端之间通信的规范。它主要由服务端的 schema 语言和客户端的查询语言组成。
【_查询语法和 schema 语法几乎是相等的_】。
gql
的 api 需要完整描述期望返回的数据,相对于RestFul API
减少了数据的冗余。修改一下官网的示例:
// 描述你的数据
// 定义了一个名为Project的对象类型,该类型上有三个字段,并且字段拥有不同的数据类型
type Project {
name: String
tagline: String
contributors: [User]
}
// 请求你所要的数据
// 请求project中,name值为字符串‘GraphQl’的数据,并返回他的tagline字段
{
project(name: "GraphQL") {
tagline
}
}
// 得到可预测的结果
{
"project": {
"tagline": "A query language for APIs"
}
}
gql 实体资源不能通过 URL 识别
与 gql 服务器的全部数据交互基于一个指定的
URL
通
道标准的 gql GET 请求
http://myapi/graphql?query={me{name}} { me{ name } }
标准的 gql POST 请求
content-type:application/json { "query": 查询的对象及参数, "operationName": "...", "variables": 变量形式的参数传参 } // 并且一般会发起两次请求,先发一次OPTION,
gql 文件
- 比较方便的管理 gql 接口的方式就是预先编写
.graphql
文件,方便复用和拓展。
// 在一个gql文件内声明多个query,需要命名query,并支持es6结构引用。单个query请求文件则可不命名。
query queryxxx(
$variable1: String
$variable2: [String]
){
myCoWorkers(
name:$variable1
gender:$variable2
){
name
age
gender
nation
}
}
- 也可以在请求时手动编写(需安装’graphql-tag’)
$apollo.query(
query:gql`query tagList {
tags {
id,
label
}
}`
)
ApolloClient
Apollo
是实现 gql 标准的客户端,(可以理解成使用 gql 的axios
)。各大框架和开发场景都有对应的整合库,如VueApollo
。
常用 api/选项
https://vue-apollo.netlify.app/zh-cn/api/smart-query.html#%E9%80%89%E9%A1%B9
query 查询表(可以是 query,mutation)
variables 变量
fetchPolicy 缓存选项
# cache-first[default] Apollo Client 首先对缓存执行查询。如果缓存中存在所有请求的数据,则返回该数据。否则,Apollo Client 会针对您的 GraphQL 服务器执行查询,并在缓存数据后返回该数据。 # cache-only Apollo Client 仅针对缓存执行查询。在这种情况下,它永远不会查询您的服务器。 如果缓存不包含所有请求字段的数据,则会引发错误。 # cache-and-network Apollo Client 对缓存和 GraphQL 服务器执行完整查询。如果服务器端查询的结果修改了缓存字段,则查询会自动更新。 # network-only Apollo Client 会针对您的 GraphQL 服务器执行完整查询,而无需先检查缓存。查询的结果存储在缓存中。 # no-cache 与 network-only 类似, 但不缓存结果。 # standby 使用与 cache-first 相同的逻辑,除了当基础字段值更改时此查询不会自动更新。您仍然可以使用 refetch 和 updateQueries 手动更新此查询。
pollInterval 轮询(间隔 x 毫秒)
fetchMore 加载更多(可以改变个别或全部参数发送同一个请求,需手动处理请求结果)
使用 Apollo(vue v2)
安装
Apollo
yarn add vue-apollo graphql apollo-boost # apollo-boost 是创建apollo client的懒人包,包含常用的默认值,无需繁琐的手动配置 or npm install --save vue-apollo graphql apollo-client apollo-link apollo-link-http apollo-cache-inmemory graphql-tag
封装
ApolloClient
import ApolloClient from "apollo-boost"; const $apollo = new ApolloClient({uri:'xxx'}) // or // 封装举例 // 超时 import ApolloLinkTimeout from "apollo-link-timeout"; const timeoutLink = new ApolloLinkTimeout(30000); // 缓存 import { InMemoryCache } from 'apollo-cache-inmemory' const cache = new InMemoryCache() // link const httpLink = createHttpLink({ uri: 'xxx' }); const timeoutHttpLink = timeoutLink.concat(httpLink); const apolloClient = new ApolloClient({ version:'', name:'', link: timeoutHttpLink,//同时提供时优先级高于uri,提供更精细化的配置 cache: // InMemoryCache ({......}) 缓存控制 www.apollographql.com/docs/react/caching/cache-configuration/` defaultOptions:{ watchQuery: { fetchPolicy: 'cache-and-network', errorPolicy: 'ignore', }, query: { fetchPolicy: 'network-only', errorPolicy: 'all', }, mutate: { errorPolicy: 'all', } }//'各种查询的默认策略' });
使用方法
apollo provider
使用 apollo 组件,需先生成
apollo provider
,为 vue 实例提供 apollo 能力Vue.use(VueApollo); const apolloProvider = new VueApollo({ defaultClient: apolloClient, }); new Vue({ el: "#app", // 像 vue-router 或 vuex 一样注入 apolloProvider apolloProvider, render: (h) => h(App), });
引入后之后,在你的每个 vue 组件实例上将多出$apollo 对象指向 apollo 客户端。
this.$apollo ===> {query:[....], }
并且与 data 选项平行的 apollo 选择中可以自定义各种 gql 查询,并且他们的结果将作为 vue 变量来使用
data(){ return { a:1 } }, apollo:{ fetchB:{ query:..., variables:..., fetchPolicy:..., ...各种apollo的api选项 } }
apollo 组件
在组件模版中编写 gql 查询,同时通过插槽
slot
分发请求结果,分别有ApolloQuery
,ApolloMutation
,ApolloSubscribeToMore
<template> <!-- Apollo 查询 --> <ApolloQuery :query="/* 一些查询 */"> <!-- 结果将自动更新 --> <template slot-scope="{ result: { data, loading } }"> <!-- 一些内容 --> <div v-if="loading">Loading...</div> <ul v-else> <li v-for="user of data.users" class="user"> {{ user.name }} </li> </ul> </template> </ApolloQuery> </template>
纯 api 封装
基本上没有侵入性的使用方法,封装成函数式的 api,不需要在实例中插入
Apollo Provider
和vue.use(vueApollo)
// 伪代码 import apolloclient import gql图表文件 // apollo请求基于promise export const xxxapi = async (params) => { return await $apollo.query({ query:, variables:{}, fetchPolicy, ... ...各种参数 }) }
然后在你的 js 代码中引入,熟悉的味道熟悉的配方
小结
相较于restful
少了大量处理数据的步骤,接口天然更加安全(参数类型参数数量对不上都会请求失败),apollo 功能也是十分强大(轮询,分页,缓存),再回去用 restful 会有一种略难受的感觉。并且后端的同学也表示舒服。
之后打算在别的项目里陆续试一试智能查询和 apollo 组件,看看有没有耦合度低的接入方式或者复用的 apollo 组件。