摘要:前言兩篇文章學(xué)完了基礎(chǔ)篇原理篇,接下去便是實(shí)踐的過程,這個實(shí)踐我們使用了如下技術(shù)棧去實(shí)現(xiàn)一套任務(wù)管理系統(tǒng),源碼就不公開了等穩(wěn)定后再發(fā)布。后續(xù)我所在的公司網(wǎng)關(guān)團(tuán)隊(duì)會持續(xù)實(shí)踐,爭取貢獻(xiàn)出更多的解決方案。
前言兩篇文章學(xué)完了GraphQL(基礎(chǔ)篇, 原理篇),接下去便是實(shí)踐的過程,這個實(shí)踐我們使用了如下技術(shù)棧去實(shí)現(xiàn)一套任務(wù)管理系統(tǒng),源碼就不公開了, 等穩(wěn)定后再發(fā)布。效果如下:
使用的技術(shù)棧有:
React16全特性
Antd構(gòu)建UI界面
create-react-app搭建客戶端基礎(chǔ)
react-apollo完成客戶端請求的封裝和響應(yīng)體的處理
bizcharts(g2)實(shí)現(xiàn)圖表
apollo-boost(graphql)完成客戶端數(shù)據(jù)請求
rxjs完成某部分響應(yīng)式設(shè)計(jì)
全程使用ramda.js做函數(shù)式編程
Nest框架做服務(wù)器
數(shù)據(jù)庫選擇moogoose
passport搭配jsonwebtoken做用戶認(rèn)證管理
graphql-server(@nest/graphql)實(shí)現(xiàn)服務(wù)端graphql請求的處理
如下圖:
分為兩大部分:client和server,其中client的目錄結(jié)構(gòu)如下:
各個目錄的解釋在圖中已經(jīng)體現(xiàn)。
server端的目錄結(jié)構(gòu)如下:
各個目錄的含義的解釋在圖中已經(jīng)體現(xiàn)。
因?yàn)槲覀冎饕侵vgraphql的應(yīng)用,所以其余的細(xì)節(jié)忽略不說。至于Nest框架的使用,請參考文檔Nest.js
GraphQL的實(shí)踐實(shí)踐GraphQL我們不會直接用graphql-js,而是使用功能更加豐富、社區(qū)支持更多apollo-graphql。其文檔編寫的也是很詳盡,基本上所有的問題都可以在文檔上找到答案。推薦新手可以先按照Get started來入手
客戶端的實(shí)踐因?yàn)槲覀兪褂昧?b>apollo-boost,所以在前端入口文件上,要拿這個包進(jìn)行一些初始化,得到apolloClient的實(shí)例(無關(guān)的代碼已經(jīng)去掉):
import React from "react";
import ReactDOM from "react-dom";
import { ApolloProvider } from "react-apollo";
import ApolloClient from "apollo-boost"
... ...
const GW_BASE_URL = process.env.NODE_ENV === "production" ");"/graphql" : "http://127.0.0.1:8888/graphql"
const client = new ApolloClient({
uri: GW_BASE_URL,
// 需要設(shè)置這個,這樣每次請求的時候認(rèn)證信息才會帶上
fetchOptions: {
credentials: "include",
},
// 緩存讀取配置
clientState: {
typeDefs,
resolvers,
},
// 設(shè)置這個是為了配合jwt
request: async (operation) => {
// get the authentication token from local storage if it exists
const token = localStorage.getItem("token");
operation.setContext({
headers: {
authorization: token ");${token}` : "",
Origin: location.href,
},
});
},
// 設(shè)置全局錯誤處理信息,這樣就不用每個請求都進(jìn)行error處理
onError: (errObj) => {
if (errObj.graphQLErrors) {
const errorMsg = errObj.graphQLErrors[0].message;
if (errorMsg === "身份信息已過期,請重新登錄") {
... ...
message.info(errorMsg, 3, () => location.hash = "#/user/login");
} else if (errorMsg && (errorMsg as any).statusCode === 403) {
message.error("權(quán)限不足,請不要重試");
} else {
message.error(errorMsg);
}
}
},
});
ReactDOM.render(
,
document.getElementById("root"),
);
頁面級別的使用
每個頁面都會新建三個文件:
graphql.ts index.scss index.tsx
其中graphql.ts定義了客戶端的請求,比如:
import gql from "graphql-tag";
// 用來查詢所有的用戶
export const QUERY_USERS = gql`
query {
userList {
id
roles
team
mobile
staffCode
email
username
}
}
`;
而后在index.tsx文件中就可以使用這個查詢語句,如下:
整個流程是很清晰的,因?yàn)槭褂昧藅ypescript,所以在客戶端可以引用到服務(wù)端定義的返回類型,從而提高了代碼編寫的速度。
實(shí)踐出來的問題和想法react-apollo目前發(fā)現(xiàn)了個bug,如果我返回的數(shù)據(jù)的層級太深,比如達(dá)到了4層以上,數(shù)據(jù)更新到緩存的時候便會出錯。
關(guān)于graphql的本地狀態(tài)的管理略微復(fù)雜,如果有個請求的結(jié)果從一開始就一直被所有的頁面使用,一般一些公共的信息,比如用戶名等,這種情況下想要直接拿到的話是不大可能的,需要繞一大圈去實(shí)現(xiàn),有點(diǎn)蛋疼~
分頁的功能分為游標(biāo)式和skip式,很明顯游標(biāo)式并不適用于web端,雖然游標(biāo)式對數(shù)據(jù)是非常友好的。在移動端用游標(biāo)式更加適合。
本地狀態(tài)管理是graphql的一個很厲害的功能,直接不需要任何數(shù)據(jù)管理框架,就可以實(shí)現(xiàn)數(shù)據(jù)的各種操作,這是一大亮點(diǎn)!
apollo-graphql也提供了開發(fā)者工具,可以在瀏覽器實(shí)時預(yù)覽當(dāng)前緩存的所有數(shù)據(jù)Developer tools
因?yàn)榉?wù)端使用了Nest.js,所以沒有直接用apollo提供的服務(wù)器,而是用了Nest框架封裝出來適用于Nest框架的graphql包graphql。該包還是提供了很多功能的。
在app.modules.ts中,我們要去初始化graphql模塊(無關(guān)代碼已忽略):
@Module({
imports: [
GraphQLModule.forRoot({
// 指定服務(wù)端schema存放的位置
typePaths: ["graphql/schema.graphql"],
// 配置了該選項(xiàng),可以自動根據(jù)代碼生成schema
autoSchemaFile: path.join(__dirname, "graphql/schema.graphql"),
buildSchemaOptions: {
},
// 可以自動生成types文件
// definitions: {
// path: path.join(__dirname, "types/graphql.ts"),
// },
debug: true,
playground: true,
context: ({ req }) => ({ req }), // 一定要這里設(shè)置req到上下文中,否則在guard中是拿不到這個req參數(shù)的
}),
],
controllers: [],
providers: []
})
每個業(yè)務(wù)目錄都會存在這么些文件:
我們在dto目錄下定義三種類型文件:xx.args.ts/xx.input.ts/xx.model.ts,分別定義下面三種情況
args對應(yīng)請求不是Input類型的
input對應(yīng)請求是Input類型的
model對應(yīng)請求的響應(yīng)體
而后在xx.resolver.ts中實(shí)現(xiàn)resolve函數(shù),借助于修飾器,比如:
import { Query, Resolver, Args, Mutation } from "@nestjs/graphql"
@Resolver("User")
export class UserResolver {
@Query(returns => [UserItem])
... ...
async userList(): Promise{
return this.userService.getUserList();
}
}
UserItem在這里(user.model.ts)定義:
import { ObjectType, Field, ID, registerEnumType, Int } from "type-graphql"
... ...
@ObjectType()
export class UserItem {
@Field(type => ID, {nullable: true})
_id");true})
username");true})
email");
如此便完成了整個服務(wù)端數(shù)據(jù)流的過程。看著是不是很easy啊?
數(shù)據(jù)庫的model和graphQL定義的model大致相同,二者如何更好地契合在一起?目前社區(qū)并沒有給出對應(yīng)的解決方案。
因?yàn)間raphql只有一個endpoint,所以打印請求就不能像之前restful那樣,需要一個與之對應(yīng)的打印方案
如何結(jié)合swagger實(shí)現(xiàn)文檔級別的呈現(xiàn)?亦或是不需要swagger,而是依靠schema去呈現(xiàn)文檔給客戶端,值的深入研究,并給出解決方案
graphql號稱解決版本的兼容性問題是輕而易舉的,目前在本項(xiàng)目中并沒有體現(xiàn)到。
至此,三篇關(guān)于GraphQL的文章到此結(jié)束了,花了很多時間斷斷續(xù)續(xù)地學(xué)習(xí),希望可以給大家呈現(xiàn)一份不一樣地文章,供大家思考。后續(xù)我所在的公司網(wǎng)關(guān)團(tuán)隊(duì)會持續(xù)實(shí)踐GraphQL,爭取貢獻(xiàn)出更多的解決方案。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/7846.html
摘要:分鐘學(xué)是一個系列,簡單暴力,包學(xué)包會。一旦組件掛載后,會自動進(jìn)行數(shù)據(jù)請求,前提是客戶端提供的和后端的相符。如果回調(diào)返回直接不作請求。在組件內(nèi)進(jìn)行分頁請求之前提到了,這個裝飾器為添加了對象,其中有個函數(shù)為。 21 分鐘學(xué) apollo-client 是一個系列,簡單暴力,包學(xué)包會。 搭建 Apollo client 端,集成 redux使用 apollo-client 來獲取數(shù)據(jù)修改本...
摘要:本文實(shí)例代碼什么是是一種面向數(shù)據(jù)的查詢風(fēng)格。概述前端的開發(fā)隨著框架全面普及,組件化開發(fā)也隨之成為大勢所趨,各個組件分別管理著各自的狀態(tài),組件化給前端仔帶來便利的同時也帶來了一些煩惱。 showImg(https://segmentfault.com/img/remote/1460000018479542?w=4928&h=3280); 本文首先介紹了 GraphQL,再通過 Mongo...
摘要:學(xué)習(xí)之道簡體中文版通往實(shí)戰(zhàn)大師之旅掌握最簡單,且最實(shí)用的教程。前言學(xué)習(xí)之道這本書使用路線圖中的精華部分用于傳授,并將其融入一個獨(dú)具吸引力的真實(shí)世界的具體代碼實(shí)現(xiàn)。完美展現(xiàn)了的優(yōu)雅。膜拜的學(xué)習(xí)之道是必讀的一本書。 《React 學(xué)習(xí)之道》The Road to learn React (簡體中文版) 通往 React 實(shí)戰(zhàn)大師之旅:掌握 React 最簡單,且最實(shí)用的教程。 showIm...
摘要:初始化項(xiàng)目使用初始化項(xiàng)目安裝項(xiàng)目結(jié)構(gòu)如下接口所有接口對封裝接下來對進(jìn)行封裝,加上中間件實(shí)現(xiàn)類似于攔截器的效果。 Graphql嘗鮮 在只學(xué)習(xí)graphql client端知識的過程中,我們常常需要一個graphql ide來提示graphql語法,以及實(shí)現(xiàn)graphql的server端來進(jìn)行練手。graphql社區(qū)提供了graphiql讓我們使用 graphiql (npm):一個交互...
摘要:區(qū)塊鏈最早出現(xiàn)在比特幣開元項(xiàng)目中。了不起的社會學(xué)實(shí)驗(yàn)比特幣的誕生年化名中本聰?shù)娜税l(fā)布比特幣白皮書,并在年公開了實(shí)現(xiàn)代碼比特幣的意義和價(jià)值比特幣首次真正從實(shí)踐意義上實(shí)現(xiàn)了安全可靠的去中心化數(shù)字貨幣機(jī)制。 區(qū)塊鏈最早出現(xiàn)在比特幣開元項(xiàng)目中。比特幣在誕生和發(fā)展過程中,借鑒了來自數(shù)字貨幣、密碼學(xué)、博弈論、分布式系統(tǒng)、控制論等多個領(lǐng)域的技術(shù)成果,作為核心支撐結(jié)構(gòu)的區(qū)塊鏈技術(shù)大放異彩。 從實(shí)體貨幣...
閱讀 1811·2021-10-09 09:44
閱讀 3382·2021-09-28 09:35
閱讀 1372·2021-09-01 10:31
閱讀 1658·2019-08-30 15:55
閱讀 2697·2019-08-30 15:54
閱讀 923·2019-08-29 17:07
閱讀 1372·2019-08-29 15:04
閱讀 2001·2019-08-26 13:56