H5ES6小资前端

GraphQL 初体验:GraphQL + Node.js

2017-06-05  本文已影响4811人  与蟒唯舞
GraphQL 是什么

GraphQL is a query language created by Facebook in 2012 which provides a common interface between the client and the server for data fetching and manipulations.

The client asks for various data from the GraphQL server via queries. The response format is described in the query and defined by the client instead of the server: they are called client‐specified queries. The structure of the data is not hardcoded as in traditional REST APIs - this makes retrieving data from the server more efficient for the client.

GraphQL 是 Facebook 开发的一个应用层的数据查询语言。通过 GraphQL,客户端可以从服务端的数据集中轻松获得一个自定义结构的数据。


假设某个业务需要以下数据内容 a:

{
  user(id: 3500401) {
    id,
    name,
    isViewerFriend
  }
}

没错,这不是 json,但我们仍然可以看懂它所表示的是查询 id 为 3500401 用户的 idnameisViewerFriend 信息。

用户信息对于各个业务都是通用的,假设另外一个业务需要这样的用户信息 b:

{
  user(id: 3500401) {
    name,
    profilePicture(size: 50)  {
      uri,
      width,
      height
    }
  }
}

一般来说,用户信息对应的数据模型都是固定的,每次请求其实就是对数据做过滤和筛选。对应到数据库操作,就是数据的查询操作。如果客户端也能够发送“查询”请求,那不就可以从后端接口这个大的“数据集”中去过滤筛选业务所需要的数据了吗?

GraphQL 就是基于这样的思想来设计的。上面提到的(a)和(b)类型的数据结构就是 GraphQL 的查询内容。使用上面的查询,GraphQL 服务器会分别返回如下响应内容。

a 查询对应的响应:

{
  "user" : {
    "id": 3500401,
    "name": "Jing Chen",
    "isViewerFriend": true
  }
}

b 查询对应的响应:

{
  "user" : {
    "name": "Jing Chen",
    "profilePicture": {
      "uri": "http: //someurl.cdn/pic.jpg",
      "width": 50,
      "height": 50
    }
  }
}

只需要改变查询内容,前端就能定制服务器返回的响应内容,这就是 GraphQL 的客户端指定查询(Client Specified Queries)。

实现 GraphQL 服务器

第一步:

npm init -f
npm install graphql express express-graphql --save
npm install babel-cli babel-preset-es2015 --save-dev
npm install -g nodemon

第二步:
在项目根目录下创建 data 目录,并在该目录下创建 data.json 文件,并输入以下内容:

{
    "1": {
        "id": "1",
        "name": "Dan"
    },
    "2": {
        "id": "2",
        "name": "Marie"
    },
    "3": {
        "id": "3",
        "name": "Jessie"
    }
}

第三步:
创建 server.js 文件,并输入以下内容:

import express from 'express'

const app = express()
const port = 3000

app.get('/', (req, res) => {
    res.send('Hello!');
});

let server = app.listen(port, function () {
    let addr = server.address();
    let bind = typeof addr === 'string' ? 'pipe ' + addr : 'port ' + addr.port;
    console.log('Listening on ' + bind);
});

命令行运行:nodemon --exec babel-node --presets=es2015 server.js,浏览器输入:http://localhost:3000 。显示 Hello!,说明你的 express 服务已经 OK 了。

第四步:
创建文件夹 /src/schema,并创建文件 index.js。并在 index.js 文件中编写GraphQL Schema。Schema 是 GraphQL 请求的入口,用户请求的
GraphQL 将会对应到具体的 Schema。

import {
    GraphQLObjectType,
    GraphQLSchema,
    GraphQLString,
    GraphQLInt
} from 'graphql'

// 我们要用的模拟数据
const data = require('../../data/data.json')

const User = new GraphQLObjectType({
    name: 'User',
    description: 'User对象',
    fields: {
        id: {
            type: GraphQLInt
        },
        name: {
            type: GraphQLString
        },
    }
});

const Query = new GraphQLObjectType({
    name: 'Query',
    fields: {
        user: {
            type: User,
            args: {
                id: {
                    type: GraphQLInt
                }
            },
            resolve: function (_, args) {
                return data[args.id];
            }
        }
    }
});

const Schema = new GraphQLSchema({
    query: Query
});

export default Schema;

第五步:
修改 server.js 文件,连接 schema。将 server.js 文件修改为以下内容:

import express from 'express'
import Schema from './src/schema'
import graphqlHTTP from 'express-graphql'

const app = express()
const port = 3000

app.use('/', graphqlHTTP({
    schema: Schema,
    graphiql: true
}));

let server = app.listen(port, function () {
    var addr = server.address();
    var bind = typeof addr === 'string' ? 'pipe ' + addr : 'port ' + addr.port;
    console.log('Listening on ' + bind);
});

这时,在浏览器中可以查看到如下界面:

在左边的空白处输入:

{
  user(id: 1) {
    name
  }
}

点击“运行”按钮,右边会出现结果:

{
  "data": {
    "user": {
      "name": "Dan"
    }
  }
}
总结

至此,我们已经搭建好了简单的 GraphQL 服务器。

上一篇下一篇

猜你喜欢

热点阅读