Open jrainlau opened 5 years ago
在使用 GraphQL (以下简称 gql)的前端项目中,往往需要等待后台同学定义好 Schema 并架设好 Playground 以后才能进行联调。如果后台同学阻塞了,前端只能被动等待。如果对于 gql 项目来说也能够和 REST 一样有一套 mock 方案就好了。经过一系列实践,我选择了 mocker-api 加 Apollo 的方案来实现。
mocker-api 是一个基于 node 实现的接口 mock 工具(前身是webpack-api-mocker,依赖于 webpack-dev-server,现在可独立运行)。由于我们的项目大都和 webpack 结合,所以这里仅简单介绍其与 webpack 结合的用法。
webpack-api-mocker
在 webpack 的 devServer 配置项中,引入以下内容:
devServer
devServer: { before (app) { require('mocker-api')(app, resolve('./mock/index.js')) } }
这样便完成了 webpack 和 mocker-api 的结合。接下来我们要到 /mock/index.js 里面写逻辑:
/mock/index.js
// /mock/index.js module.exports = { 'POST /api': (req, res) => { return res.send('Hello world') } }
此时开启 webpack-dev-server,在页面中使用 POST 方式请求 /api,即可得到内容为 Hello world 的响应。
/api
Hello world
Apollo 是一套完整的 GraphQL 实现方案,支持多种语言的服务端和客户端,在这里我们主要使用 apollo-server 来搭建前端的 gql mock 服务。
在 /mock 目录下新建 /gql 目录,再往里面分别建立 /resolvers 目录,types 目录和 index.js 入口文件。下面我们以一个”查询书籍信息“的例子来讲述这个 gql mock 服务是怎么做的。
/mock
/gql
/resolvers
types
index.js
在 /types 目录下新建 Books.js:
/types
Books.js
const { gql } = require('apollo-server') module.exports = gql` """ 书籍 """ type Book { id: ID! "标题" title: String "作者" author: String } type Query { books: [Book] } type Mutation { addBook(title: String, author: String): [Book] } `
接下来,在 /resolvers 目录底下新建 Books.js:
const books = [ { id: parseInt(Math.random() * 10000), title: 'Harry Potter and the Chamber of Secrets', author: 'J.K. Rowling' }, { id: parseInt(Math.random() * 10000), title: 'Jurassic Park', author: 'Michael Crichton' } ] module.exports = { query: { books: () => books, }, mutation: { addBook: (root, book) => { book.id = parseInt(Math.random() * 10000) books.push(book) return books } } }
最后在入口文件 index.js 里分别引入上面两个文件:
const { ApolloServer } = require('apollo-server') const typeDefs = [ require('./types/Books') ] const resolvers = { Query: { ...require('./resolvers/Books').query }, Mutation: { ...require('./resolvers/Books').mutation } } const server = new ApolloServer({ typeDefs, resolvers }) server.listen().then(({ url }) => { console.log(`🚀 Apollo server ready at ${url}`); })
运行 node ./mock/gql/index.js,即可在 localhost:4000 打开 Playground 进行调试了。
node ./mock/gql/index.js
localhost:4000
在实际的业务中,gql 接口往往被封装成形如 /api/gql 的形式,和其他的 rest 接口一起供客户端调用。为了让 /api/gql 接口能够被转发到 localhost:4000 的 Playground,我们可以利用 mocker-api 进行转发。
/api/gql
改写 /mock/index.js,为其增加一个 /api/gql 的地址:
const axios = require('axios') module.exports = { 'POST /api': (req, res) => { return res.send('Hello world') }, 'POST /api/gql': async (req, res) => { const reqBody = req.body const { data: result } = await axios({ url: 'http://localhost:4000', method: 'POST', data: reqBody }).catch(e => e) return res.send({ data: result.data }) } }
这里我使用了 axios 往 apollo-server 发起请求。
axios
此时在 webpack-dev-server 所启动的页面中往 /api/gql 发起一个 gql 请求,即可验证接口:
fetch('/api/gql', { method: 'POST', headers: { 'Accept': 'application/json', 'Content-Type': 'application/json' }, body: JSON.stringify({ query: 'query GetBooks { books { title }}' }) }) .then(res => res.json()) .then(result => console.log(result))
由于 mocker-api 支持 hot reload,所以当我们什么时候不再需要 mock 数据时,直接在 /mock/index.js 中把 'POST /api/gql' 这一段注释掉即可,无需重启 dev server。
'POST /api/gql'
至此,GraphQL 项目中的前端 mock 方案大功告成。
在使用 GraphQL (以下简称 gql)的前端项目中,往往需要等待后台同学定义好 Schema 并架设好 Playground 以后才能进行联调。如果后台同学阻塞了,前端只能被动等待。如果对于 gql 项目来说也能够和 REST 一样有一套 mock 方案就好了。经过一系列实践,我选择了 mocker-api 加 Apollo 的方案来实现。
mocker-api
mocker-api 是一个基于 node 实现的接口 mock 工具(前身是
webpack-api-mocker
,依赖于 webpack-dev-server,现在可独立运行)。由于我们的项目大都和 webpack 结合,所以这里仅简单介绍其与 webpack 结合的用法。在 webpack 的
devServer
配置项中,引入以下内容:这样便完成了 webpack 和 mocker-api 的结合。接下来我们要到
/mock/index.js
里面写逻辑:此时开启 webpack-dev-server,在页面中使用 POST 方式请求
/api
,即可得到内容为Hello world
的响应。Apollo
Apollo 是一套完整的 GraphQL 实现方案,支持多种语言的服务端和客户端,在这里我们主要使用 apollo-server 来搭建前端的 gql mock 服务。
在
/mock
目录下新建/gql
目录,再往里面分别建立/resolvers
目录,types
目录和index.js
入口文件。下面我们以一个”查询书籍信息“的例子来讲述这个 gql mock 服务是怎么做的。在
/types
目录下新建Books.js
:接下来,在
/resolvers
目录底下新建Books.js
:最后在入口文件
index.js
里分别引入上面两个文件:运行
node ./mock/gql/index.js
,即可在localhost:4000
打开 Playground 进行调试了。使用 mocker-api 把请求转发到本地的 Playground
在实际的业务中,gql 接口往往被封装成形如
/api/gql
的形式,和其他的 rest 接口一起供客户端调用。为了让/api/gql
接口能够被转发到localhost:4000
的 Playground,我们可以利用 mocker-api 进行转发。改写
/mock/index.js
,为其增加一个/api/gql
的地址:此时在 webpack-dev-server 所启动的页面中往
/api/gql
发起一个 gql 请求,即可验证接口:由于 mocker-api 支持 hot reload,所以当我们什么时候不再需要 mock 数据时,直接在
/mock/index.js
中把'POST /api/gql'
这一段注释掉即可,无需重启 dev server。至此,GraphQL 项目中的前端 mock 方案大功告成。