国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

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

Drinkey / 2571人閱讀

摘要:前言兩篇文章學(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請求的處理

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

如下圖:

分為兩大部分:clientserver,其中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

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

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

服務(wù)端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: []
})

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

每個業(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啊?

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

    數(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

相關(guān)文章

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

    摘要:分鐘學(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ù)修改本...

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

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

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

    摘要:學(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...

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

    摘要:初始化項(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):一個交互...

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

    摘要:區(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í)體貨幣...

    rozbo 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<