Apollo Server: GraphQL 数据分页概述

分页概述

由于Relay中的分页比较复杂, 本文不使用Relay的方式进行分页, 使用自定义GraphQL分页类型的方式进行分页.

REST的分页方式:

https://meta.discourse.org/articles?p=1

GraphQL查询分页

{
  articles {
    total_items # 总数
    page_no     # 当前页号
    page_items  # 每页结果数
    pages       # 总页数
    rows: {     # 分页结果
      title,
      author,
      published_at
    }
  }
}

自定义分页

首先我们需要定义一个GraphQL的分页类型, 对于上述文章例子, 我们定义一个ArticlePagination类型如下:

# 文章分页对象
type ArticlePagination {

  # 总共有多少条数据
  total_items: Int!

  # 总共有多少页
  pages: Int!

  # 当前页号
  page_no: Int!

  # 每页显示多少条数据
  page_items: Int!

  # 分页列表
  rows: [Article]
}

然后在我们的查询字段中返回这个分页对象

type Query {
  ...
  articles(page_no: Int!, page_items: Int!): ArticlePagination
  ...
}

定义解析函数

async feedbacks(_, { page_no, page_items }) {
  return db.paginateArticles(page_no, page_items)
}

上述说明都是我自己参考这个项目的学习成功, 由于目前开发的项目不是开源项目, 所以就没有完整的演示代码了.

要点

  • 使用了 ES7 的 async/await 功能, 让MySQL支持同步风格代码(对于这里是必须的, 否则解析函数会有问题)

  • 使用了 babel-node 直接运行ES6代码, 需要按照 babel-cli 工具

  • 使用 nodemon 来监视文件的变化, 实现热加载

关于 MySQL 的同步风格代码

查询方法定义

function query_sync(sql, params) {
  return new Promise((resolve, reject) => {
    pool.getConnection(function (err, connection) {
      if (err) {
        reject(err)
      } else {
        connection.query(sql, params, (err, rows) => {
          if (err) {
            reject(err)
          } else {
            resolve(rows)
          }
          connection.release()
        })
      }
    })
  })
}

对于 async/await 的数据库卡查询, await 后的函数总是返回一个Promise对象, 下面是调用方式

exports.paginateArticles = async function(){
  let limit = 10
  let offset = 0
  let stmt = 'SELECT * FROM articles LIMIT ? OFFSET ?'
  let result = await query_sync(stmt, [limit, offset])
  return result
}
  • await 只能用在 async 函数中

  • await 函数必须返回一个 Promise 对象

参考资料

你可能感兴趣的:(graphql,apollo)