官方描述:
GraphQL 既是一種用於 API 的查詢語言也是一個知足你數據查詢的運行時。 GraphQL 對你的 API 中的數據提供了一套易於理解的完整描述,使得客戶端可以準確地得到它須要的數據,並且沒有任何冗餘,也讓 API 更容易地隨着時間推移而演進,還能用於構建強大的開發者工具。javascript
// 兩趟查詢,難以拓展 GET /user/111 GET /article/1001?comment=2
// 一趟查詢,易於擴展 { article (id: 1001){ title, author, time, comments (first: 2) nickname, time, content } }, user (id: 111){ nickname, photo, sign } }
GraphQL爲express和koa提供了插件,能夠方便的搭建GraphQL服務器。
看下面的代碼:前端
var express = require('express'); var graphqlHTTP = require('express-graphql'); var { buildSchema } = require('graphql'); // 使用 GraphQL schema language 構建 schema var schema = buildSchema(` input MessageInput { content: String author: String } type Message { id: ID! content: String author: String } type Query { getMessage(id: ID!): Message } type Mutation { createMessage(input: MessageInput): Message updateMessage(id: ID!, input: MessageInput): Message } `); // 若是 Message 擁有複雜字段,咱們把它們放在這個對象裏面。 class Message { constructor(id, {content, author}) { this.id = id; this.content = content; this.author = author; } } // 映射 username 到 content var fakeDatabase = {}; var root = { getMessage: function ({id}) { if (!fakeDatabase[id]) { throw new Error('no message exists with id ' + id); } return new Message(id, fakeDatabase[id]); }, createMessage: function ({input}) { // Create a random id for our "database". var id = require('crypto').randomBytes(10).toString('hex'); fakeDatabase[id] = input; return new Message(id, input); }, updateMessage: function ({id, input}) { if (!fakeDatabase[id]) { throw new Error('no message exists with id ' + id); } // This replaces all old data, but some apps might want partial update. fakeDatabase[id] = input; return new Message(id, input); }, }; var app = express(); app.use('/graphql', graphqlHTTP({ schema: schema, rootValue: root, graphiql: true, })); app.listen(4000, () => { console.log('Running a GraphQL API server at localhost:4000/graphql'); });
咱們經過GraphQL提供的語法,創建一個schema,相似typescript的interface。
有多種基本類型:ID, String, Int, []。
Query是查詢操做,Mutation是增刪改操做。
因此這裏,咱們提供了一個getMessage的方法,返回Message類型的信息。
Mutation類型這裏咱們提供了createMessage,和updateMessage兩個方法。java
定義完schema,還須要定義方法的處理:
定義root對象進行函數處理。node
執行node index.js
。而後訪問localhost:4000/graphql就能夠看到相應的調試頁面。(前提是graphiql:true)。
這個調試頁面仍是很方便的。
打開調試頁面,先create一個message:
而後查詢這個message:
mysql
type 爲query的時候,能夠不寫query。git
var dice = 1; var sides = 6; var query = `query RollDice($dice: Int!, $sides: Int) { rollDice(numDice: $dice, numSides: $sides) }`; fetch('/graphql', { method: 'POST', headers: { 'Content-Type': 'application/json', 'Accept': 'application/json', }, body: JSON.stringify({ query, variables: { dice, sides }, }) }) .then(r => r.json()) .then(data => console.log('data returned:', data));
這是官網給的試例。fetch請求,把query傳過去就能夠啦,若是請求的是個函數,須要傳參variables。如上dice和sides兩個參數github
這裏給個鏈接mysql的schema和rootValuesql
var { buildSchema } = require('graphql'); const mysqlCon = require('./mysql'); // 使用 GraphQL schema language 構造一個 schema let count = 0; var schema = buildSchema(` type UserInfo { id: ID! name: String uid: Int age: Int sex: String createdTime: String updatedTime: String description: String } type Query { getUsers: [UserInfo] getUserById(id: ID!): UserInfo } type Mutation { invokeCount: Int } `); // root 爲每一個端點入口 API 提供一個解析器 var root = { async getUsers() { count += 1; let users = await mysqlCon.pifySelect('select * from Tab_User_Info'); console.log(users); return users; }, async getUserById({id}) { let users = await mysqlCon.pifySelect(`select * from Tab_User_Info where id=${id}`) return users[0]; }, invokeCount() { return count; } }; module.exports = { root, schema, }
mysql.jsdocker
const mysql = require('mysql'); const connection = mysql.createConnection({ host: '127.0.0.1', port: 3306, user: 'root', password: '123456', database: 'Test_User' }); connection.connect(function(err) { if (err) { console.error('error: ' + err.stack); return; } }); Object.defineProperty(connection, 'pifySelect', { value: function(sql) { return new Promise((resolve, _)=>{ connection.query(sql, function (error, results) { if (error) console.log('mysql select err:', error); resolve(results); }); }) } }) module.exports = connection
用docker搞個mysql環境:typescript
docker pull mysql:5.6 docker run -p 3306:3306 --name mysql -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.6
docker exec -it mysql bash
進入bash而後初始化一下mysql,插幾個數據用來操做。
用koa-graphql或者express-graphql啓一個服務,就能夠直接訪問啦。
facebook, twitter,github,咱們公司(toutiao)部分業務在用。