最近刚完成一个新项目,闲着没事,想着学点新东西(做前端的人都懂,技术更新实在太快了,不学容易out),听说GraphQL
现在开始火起来,大有取代传统Restful API
的方式的趋势,所以我决定学学。
什么是 GraphQL
GraphQL 是由 Facebook 创造的用于 API 的查询语言(这里查询语言所指的并不是常规意义上的类似 sql 语句的查询语言,而是一种用于前后端数据查询方式的规范)。
GraphQL 既是一种用于 API 的查询语言也是一个满足你数据查询的运行时。 GraphQL 对你的 API 中的数据提供了一套易于理解的完整描述,使得客户端能够准确地获得它需要的数据,而且没有任何冗余,也让 API 更容易地随着时间推移而演进,还能用于构建强大的开发者工具。
更多关于GraphQL
的介绍大家可以看这里
由于GraphQL
只是一套规范,不能直接使用,但社区有了很多编程语言的实现,可以直接拿过来用。这里我选用了Apollo
。
什么是 Apollo
Apollo 是基于 GraphQL 的全栈解决方案集合。包括了 apollo-client 和 apollo-server ;从后端到前端提供了对应的 lib 使得开发使用 GraphQL 更加的方便。
GraphQL
需要前后端一起才能真正发挥它的的作用,我们先在服务端实现它,这里就要用到apollo-server
。
apollo-server是一个在Node.js
上构建GraphQL
服务端的web中间件。支持express
,koa
,hapi
等框架。这里我用的是koa
。
首先,我们要安装依赖包
yarn add koa koa-bodyparser koa-router apollo-server-koa graphql graphql-tools
//or
npm install koa koa-bodyparser koa-router apollo-server-koa graphql graphql-tools
然后,编写代码
// server.js
const Koa = require('koa');
const Body = require('koa-bodyparser');
const router = require('koa-router')();
const {graphqlKoa, graphiqlKoa} = require('apollo-server-koa');
const {makeExecutableSchema} = require('graphql-tools');
const { GraphQLScalarType } = require('graphql');
const { Kind } = require('graphql/language');
const app = new Koa();
const PORT = 8090;
// 模拟数据
const users = [
{
id: 1,
name: 'J.K. Rowling',
date: new Date(2018, 5, 20)
},
{
id: 2,
name: 'Michael Crichton',
date: new Date(2018, 5, 21)
},
];
const typeDefs = `
scalar Date
type User{
id:Int!
name:String!
date: Date!
}
type Query {
users(id:Int!): [User]
user(id:Int!, name: String!):User
}
type Mutation {
addUser(name:String!):User
}
schema {
query: Query
mutation: Mutation
}
`;
const resolvers = {
Query: { // 对应到typeDefs中的 type Query
users(root, args, context) {
return users;
},
user(root, args, context, info) {
return {id: args.id, name: args.name};
}
},
Mutation: { // 对应到typeDefs中的 Mutation
addUser(root, args, context) {
return {id: 2, name: args.name};
}
},
Date: new GraphQLScalarType({ // 自定义标量类型
name: 'Date',
description: 'Date custom scalar type',
parseValue(value) {
return new Date(value); // 从客户端来的数据
},
serialize(value) {
return value.getTime(); // 发送给客户端的数据
},
parseLiteral(ast) {
if (ast.kind === Kind.INT) {
return parseInt(ast.value, 10);
}
return null;
},
}),
};
const myGraphQLSchema = makeExecutableSchema({
typeDefs,
resolvers
});
app.use(Body());
router.post('/graphql', graphqlKoa({
schema: myGraphQLSchema,
}));
router.get('/graphql', graphqlKoa({
schema: myGraphQLSchema,
}));
router.get( // 在浏览器里使用GraphiQL(可以理解成GraphQL领域的postman)
'/graphiql',
graphiqlKoa({
endpointURL: '/graphql',
}),
);
app.use(router.routes());
app.use(router.allowedMethods());
app.listen(PORT, ()=>console.log('app run in localhost:' + PORT));
接下来,执行下面命令来让我们的服务端跑起来:
node server.js
app run in localhost:8090
然后在浏览器里输入
http://localhost:8090/graphiql
,你会看到如下界面:
这时说明我们的
GraphQL
服务已成功启动。你可以在界面上进行相应的数据查询。
服务端已经成功启动,接下来就是我们的客户端了,前端本人使用的是React
框架,为了方便所以项目直接使用create-react-app
创建。
创建完成后我们进入项目目录,接着安装客户端GraphQL
查询所需要的依赖包:
yarn add react-apollo graphql-tag graphql apollo-client apollo-cache-inmemory apollo-link-http
// or
npm install react-apollo graphql-tag graphql apollo-client apollo-cache-inmemory apollo-link-http
接下来我们修改
src/index.js
里的代码:
// src/index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import registerServiceWorker from './registerServiceWorker';
import { ApolloProvider } from 'react-apollo';
import { ApolloClient } from 'apollo-client';
import { InMemoryCache } from 'apollo-cache-inmemory';
import { HttpLink } from 'apollo-link-http';
const httpLink = new HttpLink({ uri: 'http://localhost:8090/graphql' })
const client = new ApolloClient({
link: httpLink,
cache: new InMemoryCache()
})
ReactDOM.render(
<ApolloProvider client={client}>
<App />
</ApolloProvider>
, document.getElementById('root'));
registerServiceWorker();
然后修改
src/App.js
里的代码:
import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
import gql from 'graphql-tag';
import { graphql } from 'react-apollo';
class App extends Component {
render() {
console.log(this.props);
const { loading } = this.props.data;
if (loading) {
return <div>Loading...</div>
}
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<h1 className="App-title">Welcome to React</h1>
</header>
<p className="App-intro">
To get started, edit <code>src/App.js</code> and save to reload.
</p>
<p>{this.props.data.user.name}</p>
</div>
);
}
}
export default graphql(gql`
query User{
user(id: 100, name: "zhangsfs") {
id
name
}
users(id: 100) {
id
name
date
}
}
`)(App);
然后重新启动服务端代码,刷新http://localhost:8081/
,发现项目能正常运行啦。至此一个简单的GraphQL
查询就算完成了。
写在最后
上面只是一个非常简单的GraphQL
查询demo,因为本人也是初学,很多东西也还在学习阶段。如果大家有什么好的开发心得,欢迎交流。
原文发布时间为:2018年06月23日
原文作者:Sunny阳光森林
本文来源: 掘金 如需转载请联系原作者