GraphQL 官方解釋爲:一種用於 API 的查詢語言前端
(文章不斷完善中...我是寫一點更新下)node
前面有寫過一篇文章《Next.js服務端渲染框架實戰》中有提到會把數據請求與後端交互的方式從restful API方式切換成GraphQL方式。這篇文章將會嘗試用GraphQL的方式與後端進行數據交互,先立個Flag,寫個本地demo,實現基本的CURD(數據的增刪改查)操做,歡迎你們一塊兒交流討論。程序員
從入門作前端以來,前臺的數據展現由最初的混合開發模式,後端模板渲染靜態頁面,同時後端將從數據查詢到的數據變量嵌入模板,實現了前端的數據展現。後來演變到先後端分離了,前端經過異步請求,restful API的方式請求後臺接口拿到數據而後渲染到頁面。頁面的一些增刪改查操做也是經過API接口的方式跟後端作交互。那問題就來了,平常開發的時候並不能保證提早定下的API接口字段百分百的準確,這就涉及到後續較大可能性要修改接口字段了。還有更奇葩的後端提供的接口是這樣的。拋出一個接口,包含的數據層級特別深,你問他我要的字段在哪,回答是反正你要的字段在裏面,本身找去。。。後臺仁兄提早樂呵呵的下班了,你加班找來找去,頓時心中一萬個XXX.固然若是後來越來樾規範,就不存在這種噁心的接口了。但接口字段變更是不太可能消除的,那有沒有什麼方法能夠本身修改字段名稱,修改數據結構,拿到本身想要的數據?哈哈,本身寫後端接口算一個解決辦法。固然還有更好的解決辦法,就是今天的主角GraphQL了。web
題外話:我自學的編程技術,野生程序員,剛入門的時候老是迷茫不知所措。看文檔N遍仍是不知因此然,後來嘗試這按照教程去寫代碼,剛開始本身都知道寫的是什麼意思,可是寫的過程當中會遇到不少文檔裏沒有提到的東西。逼迫着你去百度找到解決辦法,那個時候也沒人指導,身邊頁也沒有搞程序開發的。自學起來真的很痛苦,後來發現學編程文檔要看。更重要的是要實踐,實際的寫代碼,會發現掌握的速度遠比看文檔要快。親身體會建議你們,想學習更透徹,直接寫代碼吧。固然如今不少時候真的能夠作到看文檔就能夠學會新技術了,那是由於有這幾年的技術積累,無論是計算機概念仍是原理都比剛開始入門時一貧如洗時的基礎好太多了,當你沉澱下來的時候你會發現,其實本身的知識體系超過了不少科班出生的程序員。最後:想深刻理解技術原理,直接寫代碼吧!express
正式開始: 技術棧很簡單:Express+GraphQLnpm
這裏會展現一個基於 Express web服務器的一個 GraphQL API 服務端參考實現.首先新建一個文件夾express,在當前文件夾執行編程
npm install express express-graphql graphql faker --save
複製代碼
在express 文件夾下新建 server.js文件,文件內容先丟出來,而後逐句解釋說明json
var express = require('express'); var graphqlHTTP = require('express-graphql'); var { buildSchema } = require('graphql'); var faker = require('faker'); var randomName = faker.name.findName(); // Rowan Nikolaus var randomEmail = faker.internet.email(); // Kassandra.Haley@erich.biz var randomCard = faker.helpers.createCard(); // random contact card containing many properties var { graphql, GraphQLSchema, GraphQLObjectType, GraphQLString, GraphQLInt, GraphQLList, GraphQLFloat, GraphQLID } = require('graphql'); const articleType = new GraphQLObjectType({ name: 'Citys', fields: { time: { type: GraphQLString }, title: { type: GraphQLString }, order: { type: GraphQLInt} } }) var Articleschema = new GraphQLSchema({ query: new GraphQLObjectType({ name: 'RootQueryType', fields: { id: { type: GraphQLID, description: '惟一id', args: { id: { // 這裏定義參數,包括參數類型和默認值 type: GraphQLID, defaultValue: 1 } }, resolve : (_, args) => { console.log(_, args.id) return Number(1 + args.id) } }, hashed:{ type: GraphQLFloat, description: '隨機值', resolve : () => { return Math.random() } }, name: { type: GraphQLString, description: '姓名', resolve : () => { return randomName } }, hello: { type: new GraphQLList(articleType), resolve() { return [ {'time':'2019-2-1', 'title':'武漢', 'order':1}, {'time':'2019-2-2', 'title':'南昌', 'order':2}, {'time':'2019-2-3', 'title':'貴陽', 'order':3}, ] } }, age: { type: GraphQLString, resolve: () => 18 }, list: { type: new GraphQLList(articleType), description: '城市信息數組', resolve: async (_, args) => { return await [ {'time':'2019-2-1', 'title':'武漢', 'order':1}, {'time':'2019-2-2', 'title':'南昌', 'order':2}, {'time':'2019-2-3', 'title':'貴陽', 'order':3}, ] } }, } }) }); var Commentschema = new GraphQLSchema({ query: new GraphQLObjectType({ name: 'RootQueryType', fields: { id: { type: GraphQLID, description: '惟一id', args: { id: { // 這裏定義參數,包括參數類型和默認值 type: GraphQLID, defaultValue: 1 } }, resolve : (_, args) => { console.log(_, args.id) return Number(1 + args.id) } }, hashed:{ type: GraphQLFloat, description: '隨機值', resolve : () => { return Math.random() } }, name: { type: GraphQLString, description: '姓名', resolve : () => { return randomName } }, hello: { type: new GraphQLList(articleType), resolve() { return [ {'time':'2019-2-1', 'title':'武漢', 'order':1}, {'time':'2019-2-2', 'title':'南昌', 'order':2}, {'time':'2019-2-3', 'title':'貴陽', 'order':3}, ] } }, age: { type: GraphQLString, resolve: () => 18 }, list: { type: new GraphQLList(articleType), description: '城市信息數組', resolve: async (_, args) => { return await [ {'time':'2019-2-1', 'title':'武漢', 'order':4}, {'time':'2019-2-2', 'title':'南昌', 'order':5}, {'time':'2019-2-3', 'title':'貴陽', 'order':6}, ] } }, } }) }); var app = express(); app.get('/', (req, res) => res.send('Welcome Graphql!')) app.use('/graphql', graphqlHTTP({ schema: Articleschema, graphiql: true, })); app.use('/comment', graphqlHTTP({ schema: Commentschema, graphiql: true })) app.listen(5000, () => console.log('Now browse to localhost:4000/graphql')); // # 每一個字段都有對應的執行函數,也就是resolver函數 複製代碼
接下來修改package.json 加入npm 執行腳本。這裏的nodemon 是node的工具,你也能夠直接用node server.js.可是沒法自動監聽 server.js 文件修改後自動重啓。nodemon 能夠實現server.js 文件修改後自動重啓服務。後端
{ "scripts": { "dev":"nodemon server.js" }, "dependencies": { "express": "^4.16.4", "express-graphql": "^0.7.1", "graphql": "^14.1.1" }, "devDependencies": { "faker": "^4.1.0" } } 複製代碼