小程序云开发支持graphql
发布于 9 个月前 作者 junlin 2981 次浏览 来自 分享

先看效果

query-schema:

  query GetAll(
    $dice: Int!
    $sides: Int
    $firstName: String
    $lastName: String
  ) {
    rollDice(numDice: $dice, numSides: $sides)
    getName(firstName: $firstName, lastName: $lastName)
  }

request:

response:

log: 配合apollo

const {data} = useQuery(GQL,{
    variables: {
      dice: 1,
      sides: 3,
      firstName: 'Yang',
      lastName: 'Robot'
    }
  })
console.log('data', data)

为什么要使用graphql?RESTFUL的方式不好吗?

1. 免去API文档的维护

  1. 直接根据schema查看接口名和参数

2. 可以合并请求,减少客户端等待时间

  1. 多个并行请求合并在一个graphql请求里
  2. 依赖关系的请求直接通过ResolveProperty处理成一个请求
    如:friend.friend.friend,在server实现friend的friend属性解析后,可以只通过一个请求获取结果。而REASTFUL需要异步请求3次

3. 声明式数据获取

  1. 返回数据格式符合预期
  2. 数据字段类型符合预期

小程序云开发服务端实现graphql-server的思路

  1. client将query-string等通过小程序云开发请求传到server
  2. server通过graphql将query-string转换成AST
  3. 将AST对比schema和rootValue,运行对应的resolver函数,获取数据
  4. 根据query格式化数据
  5. 最后将数据传给client

小程序云开发怎么使用graphql

server端

1. 新建graphql云函数

2. 安装wx-server-graphql依赖

npm install --save wx-server-graphql

3. 创建graphql服务

// 云函数入口文件
const cloud = require('wx-server-sdk')
const { graphqlWXServer } = require('wx-server-graphql')
var { buildSchema } = require('graphql')
// 使用 GraphQL Schema Language 创建一个 schema
var schema = buildSchema(`
  type Query {
    rollDice(numDice: Int!, numSides: Int): [Int]
    getName(firstName: String, lastName: String): String
  }
`)
// root 提供所有 API 入口端点相应的解析器函数
var root = {
  getName: (args, context) => {
    const { firstName, lastName } = args
    return `${firstName} ${lastName}`
  },
  rollDice: (args, context) => {
    const { numDice, numSides } = args
    return [numDice, numSides]
  }
}
// 云函数入口函数
exports.main = async (event, context) => {
  const wxContext = cloud.getWXContext()
  return await graphqlWXServer({
    wxParams: event,
    context: wxContext,
    schema: schema,
    rootValue: root
  })
}

client端

1. 配合apollo实现client

import React from 'react'
import { ApolloClient } from 'apollo-client'
import { ApolloProvider } from '[@apollo](/user/apollo)/react-hooks'
import { InMemoryCache } from 'apollo-cache-inmemory'
import { ApolloLink, Observable } from 'apollo-link'
import { print } from 'graphql/language/printer'
// 利用link重置apolloClient请求grapql的方式为wx.cloud.callFunction
// 参考文档 https://www.apollographql.com/blog/apollo-link-creating-your-custom-graphql-client-c865be0ce059/
class WXLink extends ApolloLink {
  constructor(options = {}) {
    super()
    this.options = options
  }
  request(operation) {
    return new Observable(observer => {
      wx.cloud.callFunction({
        name: this.options.name || 'graphql',
        data: {
          ...operation,
          query: print(operation.query)
        },
        success: function(res) {
          observer.next(res.result)
          observer.complete()
        },
        fail: observer.error
      })
    })
  }
}
wx.cloud.init({
  env: 'env-id',
})
const client = new ApolloClient({
  link: new WXLink({
    name: 'graphql',
  }),
  cache: new InMemoryCache(),
})
export const Provider = ({ children, ...props }) => (
  <ApolloProvider client={client}>{children}</ApolloProvider>
)

2. 编写query,发起请求

import { useQuery } from '[@apollo](/user/apollo)/react-hooks'
import gql from 'graphql-tag'
const GET_NAME = gql`
  query GetAll(
    $dice: Int!
    $sides: Int
    $firstName: String
    $lastName: String
  ) {
    rollDice(numDice: $dice, numSides: $sides)
    getName(firstName: $firstName, lastName: $lastName)
  }
`
const result = useQuery(GET_NAME, {
    variables: {
      dice: 1,
      sides: 3,
      firstName: 'Yang',
      lastName: 'Robot'
    }
  })
console.log('data', result.data)

NPM

https://www.npmjs.com/package/wx-server-graphql

Github

https://github.com/Yrobot/wx-server-graphql

如果喜欢的话就去github点个赞吧
希望 wx-server-graphql 可以节约大家的开发时间

5 回复

如果在server端部署了文件上传,用小程序怎么向graphql server上传文件?

如果在server端部署了文件上传,用小程序怎么向graphql server上传文件?

如果在server端部署了文件上传,用小程序怎么向graphql server上传文件?

如果在server端部署了文件上传,用小程序怎么向graphql server上传文件?

如果在server端部署了文件上传,用小程序怎么向graphql server上传文件?

回到顶部