亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

GraphQL學(xué)習(xí)之實(shí)踐篇

Drinkey / 2650人閱讀

摘要:前言兩篇文章學(xué)完了基礎(chǔ)篇原理篇,接下去便是實(shí)踐的過(guò)程,這個(gè)實(shí)踐我們使用了如下技術(shù)棧去實(shí)現(xiàn)一套任務(wù)管理系統(tǒng),源碼就不公開(kāi)了等穩(wěn)定后再發(fā)布。后續(xù)我所在的公司網(wǎng)關(guān)團(tuán)隊(duì)會(huì)持續(xù)實(shí)踐,爭(zhēng)取貢獻(xiàn)出更多的解決方案。

前言

兩篇文章學(xué)完了GraphQL(基礎(chǔ)篇, 原理篇),接下去便是實(shí)踐的過(guò)程,這個(gè)實(shí)踐我們使用了如下技術(shù)棧去實(shí)現(xiàn)一套任務(wù)管理系統(tǒng),源碼就不公開(kāi)了, 等穩(wěn)定后再發(fā)布。效果如下:

使用的技術(shù)棧有:

    React16全特性

    Antd構(gòu)建UI界面

    create-react-app搭建客戶端基礎(chǔ)

    react-apollo完成客戶端請(qǐng)求的封裝和響應(yīng)體的處理

    bizcharts(g2)實(shí)現(xiàn)圖表

    apollo-boost(graphql)完成客戶端數(shù)據(jù)請(qǐng)求

    rxjs完成某部分響應(yīng)式設(shè)計(jì)

    全程使用ramda.js做函數(shù)式編程

    Nest框架做服務(wù)器

    數(shù)據(jù)庫(kù)選擇moogoose

    passport搭配jsonwebtoken做用戶認(rèn)證管理

    graphql-server(@nest/graphql)實(shí)現(xiàn)服務(wù)端graphql請(qǐng)求的處理

項(xiàng)目結(jié)構(gòu)

如下圖:

分為兩大部分:clientserver,其中client的目錄結(jié)構(gòu)如下:

各個(gè)目錄的解釋在圖中已經(jīng)體現(xiàn)。

server端的目錄結(jié)構(gòu)如下:

各個(gè)目錄的含義的解釋在圖中已經(jīng)體現(xiàn)。

因?yàn)槲覀冎饕侵vgraphql的應(yīng)用,所以其余的細(xì)節(jié)忽略不說(shuō)。至于Nest框架的使用,請(qǐng)參考文檔Nest.js

GraphQL的實(shí)踐

實(shí)踐GraphQL我們不會(huì)直接用graphql-js,而是使用功能更加豐富、社區(qū)支持更多apollo-graphql。其文檔編寫的也是很詳盡,基本上所有的問(wèn)題都可以在文檔上找到答案。推薦新手可以先按照Get started來(lái)入手

客戶端的實(shí)踐

初始化

因?yàn)槲覀兪褂昧?b>apollo-boost,所以在前端入口文件上,要拿這個(gè)包進(jìn)行一些初始化,得到apolloClient的實(shí)例(無(wú)關(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è)置這個(gè),這樣每次請(qǐng)求的時(shí)候認(rèn)證信息才會(huì)帶上
  fetchOptions: {
    credentials: "include",
  },
  // 緩存讀取配置
  clientState: {
    typeDefs,
    resolvers,
  },
  // 設(shè)置這個(gè)是為了配合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è)置全局錯(cuò)誤處理信息,這樣就不用每個(gè)請(qǐng)求都進(jìn)行error處理
  onError: (errObj) => {
    if (errObj.graphQLErrors) {
      const errorMsg = errObj.graphQLErrors[0].message;
      if (errorMsg === "身份信息已過(guò)期,請(qǐng)重新登錄") {
        ... ...
        message.info(errorMsg, 3, () => location.hash = "#/user/login");
      } else if (errorMsg && (errorMsg as any).statusCode === 403) {
        message.error("權(quán)限不足,請(qǐng)不要重試");
      } else {
        message.error(errorMsg);
      }
    }
  },
});

ReactDOM.render(
  
    
      
    
  ,
  document.getElementById("root"),
);

頁(yè)面級(jí)別的使用

每個(gè)頁(yè)面都會(huì)新建三個(gè)文件:

graphql.ts
index.scss
index.tsx

其中graphql.ts定義了客戶端的請(qǐng)求,比如:

import gql from "graphql-tag";

// 用來(lái)查詢所有的用戶
export const QUERY_USERS = gql`
  query {
    userList {
      id
      roles
      team
      mobile
      staffCode
      email
      username
    }
  }
`;

而后在index.tsx文件中就可以使用這個(gè)查詢語(yǔ)句,如下:

整個(gè)流程是很清晰的,因?yàn)槭褂昧藅ypescript,所以在客戶端可以引用到服務(wù)端定義的返回類型,從而提高了代碼編寫的速度。

實(shí)踐出來(lái)的問(wèn)題和想法

    react-apollo目前發(fā)現(xiàn)了個(gè)bug,如果我返回的數(shù)據(jù)的層級(jí)太深,比如達(dá)到了4層以上,數(shù)據(jù)更新到緩存的時(shí)候便會(huì)出錯(cuò)。

    關(guān)于graphql的本地狀態(tài)的管理略微復(fù)雜,如果有個(gè)請(qǐng)求的結(jié)果從一開(kāi)始就一直被所有的頁(yè)面使用,一般一些公共的信息,比如用戶名等,這種情況下想要直接拿到的話是不大可能的,需要繞一大圈去實(shí)現(xiàn),有點(diǎn)蛋疼~

    分頁(yè)的功能分為游標(biāo)式和skip式,很明顯游標(biāo)式并不適用于web端,雖然游標(biāo)式對(duì)數(shù)據(jù)是非常友好的。在移動(dòng)端用游標(biāo)式更加適合。

    本地狀態(tài)管理是graphql的一個(gè)很厲害的功能,直接不需要任何數(shù)據(jù)管理框架,就可以實(shí)現(xiàn)數(shù)據(jù)的各種操作,這是一大亮點(diǎn)!

    apollo-graphql也提供了開(kāi)發(fā)者工具,可以在瀏覽器實(shí)時(shí)預(yù)覽當(dāng)前緩存的所有數(shù)據(jù)Developer tools

服務(wù)端實(shí)踐

因?yàn)榉?wù)端使用了Nest.js,所以沒(méi)有直接用apollo提供的服務(wù)器,而是用了Nest框架封裝出來(lái)適用于Nest框架的graphql包graphql。該包還是提供了很多功能的。

服務(wù)端GraphQL的初始化

app.modules.ts中,我們要去初始化graphql模塊(無(wú)關(guān)代碼已忽略):

@Module({
  imports: [
    GraphQLModule.forRoot({
      // 指定服務(wù)端schema存放的位置
      typePaths: ["graphql/schema.graphql"],
      // 配置了該選項(xiàng),可以自動(dòng)根據(jù)代碼生成schema
      autoSchemaFile: path.join(__dirname, "graphql/schema.graphql"),
      buildSchemaOptions: {
      },
      // 可以自動(dòng)生成types文件
      // definitions: {
      //   path: path.join(__dirname, "types/graphql.ts"),
      // },
      debug: true,
      playground: true,
      context: ({ req }) => ({ req }), // 一定要這里設(shè)置req到上下文中,否則在guard中是拿不到這個(gè)req參數(shù)的
    }),
  ],
  controllers: [],
  providers: []
})

服務(wù)端業(yè)務(wù)層級(jí)的實(shí)現(xiàn)

每個(gè)業(yè)務(wù)目錄都會(huì)存在這么些文件:

我們?cè)?b>dto目錄下定義三種類型文件:xx.args.ts/xx.input.ts/xx.model.ts,分別定義下面三種情況

    args對(duì)應(yīng)請(qǐng)求不是Input類型的

    input對(duì)應(yīng)請(qǐng)求是Input類型的

    model對(duì)應(yīng)請(qǐ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");

如此便完成了整個(gè)服務(wù)端數(shù)據(jù)流的過(guò)程??粗遣皇呛躤asy???

服務(wù)端實(shí)踐的思考

    數(shù)據(jù)庫(kù)的model和graphQL定義的model大致相同,二者如何更好地契合在一起?目前社區(qū)并沒(méi)有給出對(duì)應(yīng)的解決方案。

    因?yàn)間raphql只有一個(gè)endpoint,所以打印請(qǐng)求就不能像之前restful那樣,需要一個(gè)與之對(duì)應(yīng)的打印方案

    如何結(jié)合swagger實(shí)現(xiàn)文檔級(jí)別的呈現(xiàn)?亦或是不需要swagger,而是依靠schema去呈現(xiàn)文檔給客戶端,值的深入研究,并給出解決方案

    graphql號(hào)稱解決版本的兼容性問(wèn)題是輕而易舉的,目前在本項(xiàng)目中并沒(méi)有體現(xiàn)到。

最后

至此,三篇關(guān)于GraphQL的文章到此結(jié)束了,花了很多時(shí)間斷斷續(xù)續(xù)地學(xué)習(xí),希望可以給大家呈現(xiàn)一份不一樣地文章,供大家思考。后續(xù)我所在的公司網(wǎng)關(guān)團(tuán)隊(duì)會(huì)持續(xù)實(shí)踐GraphQL,爭(zhēng)取貢獻(xiàn)出更多的解決方案。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/7846.html

相關(guān)文章

  • 21 分鐘學(xué) apollo-client 系列:獲取數(shù)據(jù)

    摘要:分鐘學(xué)是一個(gè)系列,簡(jiǎn)單暴力,包學(xué)包會(huì)。一旦組件掛載后,會(huì)自動(dòng)進(jìn)行數(shù)據(jù)請(qǐng)求,前提是客戶端提供的和后端的相符。如果回調(diào)返回直接不作請(qǐng)求。在組件內(nèi)進(jìn)行分頁(yè)請(qǐng)求之前提到了,這個(gè)裝飾器為添加了對(duì)象,其中有個(gè)函數(shù)為。 21 分鐘學(xué) apollo-client 是一個(gè)系列,簡(jiǎn)單暴力,包學(xué)包會(huì)。 搭建 Apollo client 端,集成 redux使用 apollo-client 來(lái)獲取數(shù)據(jù)修改本...

    robin 評(píng)論0 收藏0
  • GraphQL 從入門到實(shí)踐

    摘要:本文實(shí)例代碼什么是是一種面向數(shù)據(jù)的查詢風(fēng)格。概述前端的開(kāi)發(fā)隨著框架全面普及,組件化開(kāi)發(fā)也隨之成為大勢(shì)所趨,各個(gè)組件分別管理著各自的狀態(tài),組件化給前端仔帶來(lái)便利的同時(shí)也帶來(lái)了一些煩惱。 showImg(https://segmentfault.com/img/remote/1460000018479542?w=4928&h=3280); 本文首先介紹了 GraphQL,再通過(guò) Mongo...

    Blackjun 評(píng)論0 收藏0
  • 【搶先領(lǐng)】《React 學(xué)習(xí)之道》我們翻譯了一本最簡(jiǎn)單,且最實(shí)用的 React 實(shí)戰(zhàn)教程……

    摘要:學(xué)習(xí)之道簡(jiǎn)體中文版通往實(shí)戰(zhàn)大師之旅掌握最簡(jiǎn)單,且最實(shí)用的教程。前言學(xué)習(xí)之道這本書使用路線圖中的精華部分用于傳授,并將其融入一個(gè)獨(dú)具吸引力的真實(shí)世界的具體代碼實(shí)現(xiàn)。完美展現(xiàn)了的優(yōu)雅。膜拜的學(xué)習(xí)之道是必讀的一本書。 《React 學(xué)習(xí)之道》The Road to learn React (簡(jiǎn)體中文版) 通往 React 實(shí)戰(zhàn)大師之旅:掌握 React 最簡(jiǎn)單,且最實(shí)用的教程。 showIm...

    oneasp 評(píng)論0 收藏0
  • Graphql實(shí)踐——像axios一樣使用Graphql

    摘要:初始化項(xiàng)目使用初始化項(xiàng)目安裝項(xiàng)目結(jié)構(gòu)如下接口所有接口對(duì)封裝接下來(lái)對(duì)進(jìn)行封裝,加上中間件實(shí)現(xiàn)類似于攔截器的效果。 Graphql嘗鮮 在只學(xué)習(xí)graphql client端知識(shí)的過(guò)程中,我們常常需要一個(gè)graphql ide來(lái)提示graphql語(yǔ)法,以及實(shí)現(xiàn)graphql的server端來(lái)進(jìn)行練手。graphql社區(qū)提供了graphiql讓我們使用 graphiql (npm):一個(gè)交互...

    mumumu 評(píng)論0 收藏0
  • 區(qū)塊鏈學(xué)習(xí)之區(qū)塊鏈思想的誕生(一)

    摘要:區(qū)塊鏈最早出現(xiàn)在比特幣開(kāi)元項(xiàng)目中。了不起的社會(huì)學(xué)實(shí)驗(yàn)比特幣的誕生年化名中本聰?shù)娜税l(fā)布比特幣白皮書,并在年公開(kāi)了實(shí)現(xiàn)代碼比特幣的意義和價(jià)值比特幣首次真正從實(shí)踐意義上實(shí)現(xiàn)了安全可靠的去中心化數(shù)字貨幣機(jī)制。 區(qū)塊鏈最早出現(xiàn)在比特幣開(kāi)元項(xiàng)目中。比特幣在誕生和發(fā)展過(guò)程中,借鑒了來(lái)自數(shù)字貨幣、密碼學(xué)、博弈論、分布式系統(tǒng)、控制論等多個(gè)領(lǐng)域的技術(shù)成果,作為核心支撐結(jié)構(gòu)的區(qū)塊鏈技術(shù)大放異彩。 從實(shí)體貨幣...

    rozbo 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<