GraphQL一種用爲你 API 而生的查詢語言。出自於Facebook,GraphQL很是易懂,直接看查詢語句就能知道查詢出來的數據是什麼樣的。本質上屬於API Layer層,負責前端請求的合併、數據整理等功能。前端
使用幾個簡單的例子看下GraphQL的查詢是什麼樣子的。java
{ me { name } }
查詢出來的數據格式以下:node
{ "me": { "name": "wanghao" } }
一、返回來的數據是一個json
二、返回數據格式和查詢徹底一致mysql
入參格式:git
{ user(id: 6) { name, profilePicture { width, height, url } } }
查詢出來的數據以下:github
{ "me" { "name": "wanghao," "profilePicture": { "width": 50, "height": 50, "url": "https://cdn/some.jpg" } } }
固然,profilePicture查詢時也能夠指定參數:redis
{ me { name, profilePicture(size: 300) { width, height, url } } }
輸出可能以下:spring
{ "me" { "name": "wanghao," "profilePicture": { "width": 300, "height": 300, "url": "https://cdn/300.jpg" } } }
有時候同一字段咱們想要查詢兩次,可是兩次指定的參數不一樣,好比一個用戶有多張頭像,咱們只想查詢其中的2張,能夠以下:sql
{ me { name, littlePic: profilePicture(size: 50) { width, height, url }, bigPic: profilePicture(size: 300) { width, height, url } } }
輸出結果以下:typescript
{ "me" { "name": "wanghao," "littlePic": { "width": 50, "height": 50, "url": "https://cdn/50.jpg" }, "bigPic": { "width": 300, "height": 300, "url": "https://cdn/300.jpg" } } }
更多查詢請參考:http://graphql.cn/learn/queries/
查詢只適用於數據查詢,可是每每接口還有部分新增、修改、刪除操做,這個時候就須要使用變動(Mutations)。
想要新增一條數據,簡單的變動入參以下:
mutation($inputComment: CommentInput!) { addComment(data: $inputComment) }
其中$inputComment是GraphQL中的變量寫法,具體以下:
{ "inputComment": { "postId": "5a796104fe9b131a10d9627d", "text": "測試評論部分23232" } }
返回數據直接以下:
{ "data": { "addComment": true } }
GraphQL請求時不限制get、post請求,若是是get,會自動將請求體放在query中,看下實際請求時入參是什麼樣子的:
{ query: "mutation($inputComment: CommentInput!) {↵ addComment(data: $inputComment)↵}↵↵" variables: "{↵ "inputComment": {↵"postId":"5a796104fe9b131a10d9627d",↵"text":"測試評論部分23232"↵}" }
能夠看出,請求時實際發送的是一串字符串至GraphQL服務器,GraphQL服務器會自動解析該字符串內容。
GraphQL的全部實現基本都有實現該可視化工具,進行簡單配置便可查看,express-graphql模塊配置以下:
// GraphqQL server route app.use('/graphql', graphqlHTTP(req => ({ schema, pretty: true, // 配置顯示pretty按鈕進行代碼美化 graphiql: true, // 配置開啓可視化查詢 })));
# 定義 type User { name: String, friends: [User] } #查詢 { users { name friends { name friends { name } } } }
GraphQL支持嵌套查詢,若是沒有dataloader,就會出現嚴重的N+1查詢性能問題。
Dataloader(官方網址)是由facebook推出,能大幅下降數據庫的訪問頻次,常常在Graphql場景中使用。
import Sequelize from 'sequelize' import DataLoader from 'dataloader' // 定義表結構 const sequelize = new Sequelize('test', null, null, { dialect: 'sqlite', }) const UserModel = sequelize.define('user', { name: Sequelize.STRING }) await sequelize.sync({force: true}) //插入測試數據 await [ UserModel.create({name: 'ron'}), UserModel.create({name: 'john'}), ] // 初始化DataLoader,傳入一個批處理函數 const userLoader = new DataLoader(keys => UserModel.findAll({where: {name: {$in: keys}}})) // 如下2個Load語句會被自動批處理,合併成一次數據庫的操做 await [ userLoader.load('ron'), userLoader.load('john') ]
Executing (default): SELECT id, name, createdAt, updatedAt FROM users AS user WHERE user.name IN ('ron', 'john’);
DataLoader緩存的典型應用是per-request範圍的緩存,不能取代redis等應用級別的緩存。
nestjs,官網地址:https://docs.nestjs.com,是一個使用typescript構建nodejs後端應用的框架,相似java中的spring框架:依賴注入、攔截器、過濾器、裝飾器模式等等,比較看好。
使用nestjs搭配GraphQL、typeorm、mysql實現了一個簡單的GraphQL查詢服務,查詢支持單個查詢、列表查詢、關聯查詢,變動支持修改、刪除操做,具體demo地址: https://github.com/caiya/graphql-nestjs-typeorm