天天看點

前端關于GraphQL的一點小小的了解GraphQL

GraphQL

一、介紹

官網了解一下

這個比較詳細

  • GraphQL是Facebook開發的一種資料查詢語言,并于2015年公開釋出,它是REST API的替代品,是用于前後端資料查詢方式的規範

特點:

  1. 請求需要的資料,不多不少

    例如:account中有name,age,sex,department等,可以隻取得需要的字段。

  2. 擷取多個資源,隻用一個請求.
  3. 描述所有可能類型的系統。便于維護,根據需求平滑演進,添加或者隐藏字段。
  4. 可以使用任何資料庫

GraphQL與restful的差別

restful本質就是用定義uri,通過api接口來取得資源

二、參數類型

基本參數類型

  • 基本類型:String/Int/Float/Boolean/ID,可以在schema聲明的時候直接使用。
  • [類型]代表數組,例如:[Int]代表整型數組。

schema定義結構

[外鍊圖檔轉存失敗,源站可能有防盜鍊機制,建議将圖檔儲存下來直接上傳(img-Ilhgjj0v-1628752516184)(/Users/shulun-001/Library/Application Support/typora-user-images/image-20210805155214977.png)]

自定義參數類型

#GraphQL允許使用者自定義參數類型,通常用來描述要擷取的資源的屬性。
#一般寫在schema.graphl裡頭定義類型
type Account{
	name:String
	age:Int
	sex:String
	salary(city:String):Int
}
type Query{
	account(name:String):Account	//定義一個Account屬性,然後在Account類型中進行傳回
}
           

參數傳遞

  • 和js傳遞參數一樣,小括号内定義形參,但是注意:參數需要定義類型。
  • !(歎号)代表參數不能為空

三、GraphQL clients

GraphQL 有一種一流的方法可以從查詢中提取動态值,并将它們作為單獨的字典傳遞。這些值稱為變量。

1. 查詢資料用query

[外鍊圖檔轉存失敗,源站可能有防盜鍊機制,建議将圖檔儲存下來直接上傳(img-KT836bNs-1628752516186)(/Users/shulun-001/Library/Application Support/typora-user-images/image-20210804114157114.png)]

第一行大寫(類型和之前定義的一樣),第二行小寫,傳入$user.id

GraphQL查詢規範:

1.片段(fragments)
前端關于GraphQL的一點小小的了解GraphQL

請求就用nuxt異步請求

2.mutations修改資料

[外鍊圖檔轉存失敗,源站可能有防盜鍊機制,建議将圖檔儲存下來直接上傳(img-jPmYPmIB-1628752516187)(/Users/shulun-001/Library/Containers/com.tencent.xinWeChat/Data/Library/Caches/com.tencent.xinWeChat/2.0b4.0.9/33cd611f706d6acfa48413cd90846f4d/dragImgTmp/WeChatef176becb29f23d693b7043534d856e1.png)]

例子:

const express = require('express');
const {buildSchema}=require('graphql');
const graphqlHTTP=require('express-graphql');
//定義schema,查詢和類型,mutation
const schema=buildSchema(`
  input AccountInput{
    name:String
    age:Int
    sex:String
    department:String
  }
  type Account{
    name:String
    age:Int
    sex:String
    department:String
  }
  type Mutation{
    createAccount(input:AccountInput):Account
    updateAccount(id:ID!,input:AccountInput):Account
  }
  type Query{
    account:[Account]
  }
`)
const fakeDB={};
//定義查詢對應的處理器
const root={
  account(){
    var arr=[];
    for(const key in fakeDB){
      arr.push(fakeDB[key])
    }
    return arr;
  },
  createAccount({input}){
    //相當于資料庫的儲存
    fakeDB[input.name]=input;
    //傳回儲存結果
    return fakeDB[input.name];
  },
  updateAccount({id,input}){
    //相當于資料庫的更新
    const updateAccount=Object.assign({},fakeDB[id],input);
    fakeDB[id]=updateAccount;
    //傳回資料庫
    return updatedAccount;
  }
}

const app=express();
app.use('/graphql',graphqlHTTP({
  schema:schema,
  //相當于項目中運作yarn schema
  rootValue:root,
  graphiql:true
}))

app.listen(3000)

           

3.結合資料庫寫的一個例子

const express = require('express');
const {
  buildSchema
} = require('graphql');
const graphqlHTTP = require('express-graphql');
const mysql = require('mysql');
// https://www.npmjs.com/package/mysql
var pool = mysql.createPool({
  connectionLimit: 10,
  host: 'localhost',
  user: 'root',
  password: 'root',
  database: 'xxxx'
})

//定義schema,查詢和類型,mutation
const schema = buildSchema(`
  input AccountInput{
    name:String
    age:Int
    sex:String
    department:String
  }
  type Account{
    name:String
    age:Int
    sex:String
    department:String
  }
  type Mutation{
    createAccount(input:AccountInput):Account
    deleteAccount(id:ID):Boolean
    updateAccount(id:ID!,input:AccountInput):Account
  }
  type Query{
    account:[Account]
  }
`)
const fakeDB = {};
//定義查詢對應的處理器
const root = {
  account() {
    return new Promise((resolve,reject)=>{
      pool.query('select name,age,sex,department from account',(err,results)=>{
        if(err){
          console.log('error',err.message);
          return;
        }
        const arr=[];
        for(const i=0;i<results.length;i++){
          arr.push({
            name:results[i].name,
            sex:results[i].sex,
            age:results[i].age,
            department:results[i].department,
          })
        }
        resolve(results);
      })
    })
  },
  createAccount({
    input
  }) {
    const data = {
      name: input.name,
      sex: input.sex,
      age: input.age,
      department: input.department
    }
    return new Promise((resolve, reject) => {
      pool.query('insert into accout set ?', data, (err) => {
        if (err) {
          console.log('error',err.message);
          return;
        }
        //傳回儲存結果
        resolve(data);
      })
    })
  },
  updateAccount({
   id,input
  }) {
    const data=input;
    return new Promise((resolve,reject)=>{
      pool.query('update account set?where name=?',[data,id],(err)=>{
        if(err){
          console.log('err',err.message);
          return;
        }
        resolve(data);
      })
    })    
  },
  deleteAccount({id}){
    return new Promise((resolve,reject)=>{
      pool.query('delete account where name=?',[id],(err)=>{
        if(err){
          console.log("err",err.message)
          reject(false);
          return;
        }
        resolve(true);
      })
    })
  }
}
const app = express();
//增加一個判斷權限的中間件
const middleware = (req, res, next) => {
  if (req.url.indexOf('/graphql') != -1 && req.headers.cookie.indexOf('auth')) {
    res.send(JSON.stringify({
      error: "您沒有權限通路這個接口"
    }));
    return;
  }
  next();
}
//使用中間件
app.use(middleware)

app.use('/graphql', graphqlHTTP({
  schema: schema,
  rootValue: root,
  graphiql: true
}))

app.listen(3000)
           

4.了解schema

Schema的主要用途是定義所有可供查詢的字段(field),它們最終組合成一套完整的GraphQL

API.

繼續閱讀