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

資訊專欄INFORMATION COLUMN

21 分鐘學(xué) apollo-client 系列:請(qǐng)求攔截和 FragmentMatcher

Eastboat / 2731人閱讀

摘要:分鐘學(xué)是一個(gè)系列,簡(jiǎn)單暴力,包學(xué)包會(huì)。接管了請(qǐng)求和狀態(tài)管理。一般在生產(chǎn)環(huán)境中,我們通常還希望做權(quán)限驗(yàn)證請(qǐng)求攔截等事務(wù)處理。

21 分鐘學(xué) apollo-client 是一個(gè)系列,簡(jiǎn)單暴力,包學(xué)包會(huì)。

搭建 Apollo client 端,集成 redux
使用 apollo-client 來(lái)獲取數(shù)據(jù)
修改本地的 apollo store 數(shù)據(jù)
提供定制方案

請(qǐng)求攔截

封裝修改 client 的 api
apollo store 存儲(chǔ)細(xì)節(jié)

寫(xiě)入 store 的失敗原因分析和解決方案

我們已經(jīng)搭建了最小化的 ApolloClient。

Apollo 接管了 api 請(qǐng)求和狀態(tài)管理。一般在生產(chǎn)環(huán)境中,我們通常還希望做權(quán)限驗(yàn)證、請(qǐng)求攔截等事務(wù)處理。

于是,我們就需要通過(guò) Apollo 提供的一些接口,結(jié)合自己的業(yè)務(wù)需求,定制自己的 Apollo。

網(wǎng)絡(luò)層

GraphQL 入門(mén): Apollo Client - 網(wǎng)絡(luò)層

上面這篇文章中,介紹了 Apollo 網(wǎng)絡(luò)層的基礎(chǔ)知識(shí),推薦閱讀。我只是再做一些補(bǔ)充。

fetch

Apollo 使用的是 fetch api
從源碼來(lái)看,apollo 代碼中并沒(méi)有包含 polyfill,也就是說(shuō),在低版本的瀏覽器上可能會(huì)因?yàn)槿鄙?fetch 而失敗。所以你需要安裝 isomorphic-fetch
另外,如果你碰到跨域等問(wèn)題,也是 fetch 引起的,和 apollo 沒(méi)什么關(guān)系。

const networkInterface = (createNetworkInterface({
    uri: "...",
    opts: {
        // fetch 相關(guān)的設(shè)置在這里配置
        credentials: "same-origin",
    },
}));
network middlewares

如果你使用過(guò) Express 的話,就能很容易理解這個(gè)概念。否則你也可以理解為 middleware 就是請(qǐng)求的攔截器,可以在每個(gè)請(qǐng)求發(fā)送前或發(fā)送后,攔截請(qǐng)求,對(duì)其做一些修改,再?zèng)Q定是否傳遞,也可以直接取消。

所以你可以在這里

設(shè)置 headers

權(quán)限驗(yàn)證

取消請(qǐng)求

緩存請(qǐng)求

實(shí)踐中,建議把所有的 middlewares 寫(xiě)到一個(gè)多帶帶的文件。
我個(gè)人比較喜歡寫(xiě)簡(jiǎn)化的代碼,你也可以參考我進(jìn)行配置。

middlewares.js

const wrapMiddlewares = (key) => (mws) => mws.map(mw => ({ [key]: mw }));
const wrapBeforewares = wrapMiddlewares("applyMiddleware");
const wrapAfterwares = wrapMiddlewares("applyAfterware");

// 可以看成一個(gè)沒(méi)有冗余代碼的配置表
export default function applyApolloMiddlewares(networkInterface) {
    networkInterface.use(wrapBeforewares([
        setHeaders,
    ]))
    .useAfter(wrapAfterwares([
        checkAuth,
    ]));

    return networkInterface;
}

// ---- 請(qǐng)求前 ----

function setHeaders(req, next) {
    try {
        if (!req.options.headers) {
            req.options.headers = {
                "Content-Type": "application/json;charset=utf-8",
            };
        }
    } catch (e) {
        console.error(e);
    }

    // 必須返回 next
    next();
}

// ---- 請(qǐng)求后 -----

function checkAuth({ response: res }, next) {
    try {
        // 自行處理 401 等各種 statusCode
    } catch (e) {
        console.error(e);
    }

    next();
}

建議對(duì)所有的 middlewares 包裹一層 try catch,因?yàn)槲野l(fā)現(xiàn) apollo 這個(gè)庫(kù)不能很好地報(bào)錯(cuò),經(jīng)常靜默失敗。

于是你的 createApolloClient 函數(shù)可以改寫(xiě)為

createApolloClient.js

import { ApolloClient, createNetworkInterface } from "react-apollo";
import applyApolloMiddlewares from "./middlewares";

const networkInterface = (createNetworkInterface({
    uri: "...",
    opts: {
        // fetch 相關(guān)的設(shè)置在這里配置
        credentials: "same-origin",
    },
}));

const client = new ApolloClient({
    networkInterface: applyApolloMiddlewares(networkInterface),
});

return client;
FragmentMatcher

正式請(qǐng)求中,如果你的 schema 包含了 union type,形如

content { # 類型為 Content
    ... on Article {
        id
        title
    }
    ... on Timeline {
        id
        content
    }
}

即根據(jù)返回?cái)?shù)據(jù)的類型不同,抓取不同的數(shù)據(jù),這在 GraphQL 中,使用的是 inline fragment 語(yǔ)法來(lái)解決。
而上面代碼中的 Content 這個(gè)類,本身沒(méi)有具體字段,但有許多子類,被稱為 union type。

可以看看 GraphQL 關(guān)于這一細(xì)節(jié)的描述:inline-fragments。

apollo 中使用一種啟發(fā)式的類型搜索方式,不像后端已經(jīng)存在所有的類型說(shuō)明,前端為了類型安全,必須由你來(lái)告訴 apollo,該 union type 下到底有哪些子類

否則你可能會(huì)看到這樣的報(bào)錯(cuò)

You are using the simple (heuristic) fragment matcher, but your queries contain union or interface types.
     Apollo Client will not be able to able to accurately map fragments

報(bào)錯(cuò)信息會(huì)指引你閱讀這個(gè)文檔,說(shuō)的就是我上面描述的情況:Using Fragments on unions and interfaces

為了少寫(xiě)垃圾代碼,我寫(xiě)了一些 helper,希望對(duì)你有用。

const createIntrospectionFactory = (kind) => (name, possibleTypes) => ({
    name,
    kind,
    possibleTypes: possibleTypes.map(typename => ({ name: typename })),
});

const createInterface = createIntrospectionFactory("INTERFACE");
const createUnion = createIntrospectionFactory("UNION");

export default {
    introspectionQueryResultData: {
        __schema: {
            types: [
                createInterface("Content", [
                    "Article",
                    "Timeline",
                ]),
            ]
        }
    }
};

所以你的 client 可以寫(xiě)成

import { ApolloClient, createNetworkInterface, IntrospectionFragmentMatcher } from "react-apollo";
import applyApolloMiddlewares from "./middlewares";
import fragmentMatcher from "./fragmentMatcher";

export default function createApolloClient() {
    const networkInterface = (createNetworkInterface({
        uri: "...",
        opts: {
            credentials: "same-origin",
        },
    }));

    const client = new ApolloClient({
        networkInterface: applyApolloMiddlewares(networkInterface),
        fragmentMatcher: new IntrospectionFragmentMatcher(fragmentMatcher),
    });

    return client;
}








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

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

相關(guān)文章

  • 21 分鐘學(xué) apollo-client 系列:擴(kuò)展 ApolloClient 的 api

    摘要:分鐘學(xué)是一個(gè)系列,簡(jiǎn)單暴力,包學(xué)包會(huì)。那怎么辦呢本章就教你非常簡(jiǎn)單地實(shí)現(xiàn)擴(kuò)展的。我們可以借鑒的的寫(xiě)法,為的實(shí)例添加一些自己的方法。更重要的是,也會(huì)有的效果,上一個(gè)的輸出會(huì)成為下一個(gè)的輸入,便于組合。 21 分鐘學(xué) apollo-client 是一個(gè)系列,簡(jiǎn)單暴力,包學(xué)包會(huì)。 搭建 Apollo client 端,集成 redux使用 apollo-client 來(lái)獲取數(shù)據(jù)修改本地的 ...

    levy9527 評(píng)論0 收藏0
  • 21 分鐘學(xué) apollo-client 系列:apollo store 存儲(chǔ)細(xì)節(jié)

    摘要:分鐘學(xué)是一個(gè)系列,簡(jiǎn)單暴力,包學(xué)包會(huì)。內(nèi)部通過(guò)自己的私有沒(méi)有暴露給開(kāi)發(fā)者來(lái)更新這個(gè)。相當(dāng)于這個(gè)就是自己維護(hù)的,它將所有通過(guò)得到的數(shù)據(jù)保存在這里。的生成規(guī)則根據(jù)官方文檔的說(shuō)法,在創(chuàng)建時(shí),可選設(shè)置。如果不存在,則可能出現(xiàn)。 21 分鐘學(xué) apollo-client 是一個(gè)系列,簡(jiǎn)單暴力,包學(xué)包會(huì)。 搭建 Apollo client 端,集成 redux使用 apollo-client 來(lái)...

    lavor 評(píng)論0 收藏0
  • 21 分鐘學(xué) apollo-client 系列:簡(jiǎn)單搭建

    摘要:分鐘學(xué)是一個(gè)系列,簡(jiǎn)單暴力,包學(xué)包會(huì)。其中提到了等需要后端配合的東西,徒增了配置的復(fù)雜性。如果不行,再跟隨我的簡(jiǎn)單步驟試試。環(huán)境要求請(qǐng)確保你已經(jīng)搭建了自己的環(huán)境下文在行號(hào)前添加表示刪除的原代碼,表示新增的代碼。 21 分鐘學(xué) apollo-client 是一個(gè)系列,簡(jiǎn)單暴力,包學(xué)包會(huì)。 搭建 Apollo client 端,集成 redux使用 apollo-client 來(lái)獲取數(shù)據(jù)...

    ranwu 評(píng)論0 收藏0
  • 21 分鐘學(xué) apollo-client 系列:寫(xiě)入失敗的原因解決方案

    摘要:分鐘學(xué)是一個(gè)系列,簡(jiǎn)單暴力,包學(xué)包會(huì)。一旦你丟失了,可能會(huì)導(dǎo)致寫(xiě)入失敗,或者盡管寫(xiě)入了,但本該攜帶的那一層的數(shù)據(jù)沒(méi)有寫(xiě)入。 21 分鐘學(xué) apollo-client 是一個(gè)系列,簡(jiǎn)單暴力,包學(xué)包會(huì)。 搭建 Apollo client 端,集成 redux使用 apollo-client 來(lái)獲取數(shù)據(jù)修改本地的 apollo store 數(shù)據(jù)提供定制方案 請(qǐng)求攔截 封裝修改 clie...

    Baoyuan 評(píng)論0 收藏0
  • 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

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

0條評(píng)論

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