讓咱們先回顧一下咱們如今所使用的API設計風格css
優勢:靈活、解構
缺點:因爲一個endpoint對應一個資源因此須要不少次請求html
優勢:一次請求、所得即所需
缺點:不夠靈活、高度耦合、很高的維護成本、迭代慢前端
上面是咱們兩種經常使用的接口方式,兩種都有各自的優缺點,有沒有能夠包攬全部優勢的方案呢?咱們須要一個標準的API層,那這就是GraphQL,請注意GraphQL是一個規範,是由facebook倡導的一個規範,不是一個實現。
GraphQL有下面三個定義:node
GraphQL是長什麼樣子的呢?
react
可能這樣看起來還比較難理解,沒事,咱們直接coding。git
因爲GraphQL是一種規範,它不是一種實現,若是要本身實現仍是比較難的,不用擔憂,強大的開源社區已經幫咱們準備好了,這就是Apollo開源項目。Apollo提供了豐富的後端實現(node支持:express、koa、hapi、restify等框架)和前端(React、RN、Angular、IOS、Android等)實現。官方文檔:http://dev.apollodata.com/too...。下面的實踐都是基於Apollo以nodejs的Express框架來實現的。
Demo代碼:https://github.com/jasondu/ap...github
import express from 'express'; import { graphqlExpress, graphiqlExpress, } from 'apollo-server-express'; import bodyParser from 'body-parser'; import schema from './data/schema'; // 定義GraphQL查詢格式 const GRAPHQL_PORT = 3002; const graphQLServer = express(); graphQLServer.use('/graphql', bodyParser.json(), graphqlExpress({ schema })); // 實現GraphQL接口功能 graphQLServer.use('/graphiql', graphiqlExpress({ endpointURL: '/graphql' })); // 實現GraphQL瀏覽器調試界面 graphQLServer.listen(GRAPHQL_PORT, () => console.log( `GraphiQL is now running on http://localhost:${GRAPHQL_PORT}/graphiql` ));
懂Express的童鞋應該均可以看到上面的代碼,我作一下解釋:數據庫
讓咱們看看Schema.js是怎麼寫的express
import { makeExecutableSchema, } from 'graphql-tools'; import resolvers from './resolvers'; // 定義schema const typeDefs = ` type Author { # 做者的字段有:id,名字,還有 發表的帖子 id: Int firstName: String lastName: String posts: [Post] } type Post { # 帖子的字段有下面這些,包括 這個帖子是哪一個做者寫的 id: Int title: String text: String views: Int author: Author } type Query { # 定義查詢內容 author(firstName: String, lastName: String): Author # 查詢做者信息 getFortuneCookie: String } `; const schema = makeExecutableSchema({ typeDefs, resolvers }); export default schema;
這裏用到Apollo提供的makeExecutableSchema方法,這個方法是將Schema結構的數據轉換成GraphQLSchema實例。
typeDefs裏面定義了三個格式Author,Post,Query,這裏Query就是查詢的時候返回的結構,Author,Post是解釋了在Query中的結構類型。
接下來,咱們就能夠編寫具體的實現了。npm
const resolvers = { Query: { author(root, args){ // args就是上面schema中author的入參 return { id: 1, firstName: 'Hello', lastName: 'World' }; }, }, Author: { // 定義author中的posts posts(author){ return [ { id: 1, title: 'A post', text: 'Some text', views: 2}, { id: 2, title: 'Another post', text: 'Some other text', views: 200} ]; }, }, Post: { // 定義Post裏面的author author(post){ return { id: 1, firstName: 'Hello', lastName: 'World' }; }, }, }; export default resolvers;
上面這段代碼比較簡單,就不作解釋了。
至此,咱們就完成了一個GraphQL服務端的開發,加下來咱們npm i & npm start
吶,這樣就啓動啦!打開http://localhost:3002/graphiql就能夠看到剛纔前面說的graphiql,就是GraphQL瀏覽器調試界面。
graphiql能夠支持聯想功能,能夠很是快的書寫查詢語句。
create-react-app client & yarn add react-apollo
import React, { Component } from 'react'; import logo from './logo.svg'; import './App.css'; // -------- 添加內容 -------- // import { ApolloClient, ApolloProvider, createNetworkInterface, gql, graphql, } from 'react-apollo'; // 設置接口地址 const networkInterface = createNetworkInterface({ uri: 'http://localhost:3002/graphql' }); const client = new ApolloClient({ networkInterface, }); const Test = ({ data: { loading, error, author } }) => { if (loading) { return <p>Loading ...</p>; } if (error) { return <p>{error.message}</p>; } return ( <h3>{author.firstName} {author.lastName}</h3> ); }; // 查詢語句 const query = gql` query AuthorQuery { author (firstName: "firstName", lastName: "lastName") { firstName, lastName } } `; const Gtest = graphql(query)(Test); // -------- 添加內容 -------- // class App extends Component { render() { return ( <ApolloProvider client={client}> <div className="App"> <div className="App-header"> <img src={logo} className="App-logo" alt="logo" /> <Gtest /> </div> <p className="App-intro"> To get started, edit <code>src/App.js</code> and save to reload. </p> </div> </ApolloProvider> ); } } export default App;
這裏的寫法跟redux相似,使用<ApolloProvider>包裹項目,經過graphql方法將數據注入到組件中。
而後執行yarn start 這樣項目就啓動了,以下圖
注:這裏存在跨域問題,因此服務器端須要使用cors解決跨域問題,具體看代碼。
https://dev-blog.apollodata.c...
《Tutorial: How to build a GraphQL server》講解了如何搭建node GraphQL服務器,如何定義schema,還有如何連接之前的SQL數據庫,rest等,入門必讀
https://dev-blog.apollodata.c...
《Full-stack React + GraphQL Tutorial》講解如何和客戶端結合起來,還有若是實現ws實時通訊等
https://launchpad.graphql.com...
這個是apollo提供的線上編輯器,能夠在線上編寫schema和resolve,而後能夠下載下來部署
這個網站詳細講解了如何在各類服務器客戶端使用graphql
http://taobaofed.org/blog/201...
《Node.js 服務端實踐之 GraphQL 初探》阿里在15年寫的文章