繁体   English   中英

添加自定义 header 到 apollo 客户端轮询请求

[英]Add custom header to apollo client polling request

我正在使用apollo-client库从我的Graphql服务器查询数据。 一些查询通过 apollo 轮询功能每 5 秒发送一次到服务器。

是否有一种通用方法可以将自定义 header 添加到我的轮询客户端发送的所有请求中?

两种解决方案

有两种方法可以做到这一点。 一种快速简便,适用于具有某些限制的特定查询,另一种是更安全且适用于多个查询的通用解决方案

快速简便的解决方案

优势

  • 很快
  • 和...容易

配置查询时,您可以使用其options字段进行配置,该字段具有context字段。 context的值将由网络链处理。 context本身不会发送到服务器,但如果向其添加headers字段,它将在 HTTP 请求中使用。

示例

const someQuery = graphql(gql`query { ... }`, {
  options: { 
    context: { 
      headers: { 
        "x-custom-header": "pancakes"  // this header will reach the server
      } 
    },
    // ... other options  
  }
})

使用网络链接中间件的通用解决方案

使用 Apollo,您可以添加一个 Apollo Link,它将充当中间件,并根据查询操作设置的context向请求添加自定义标头。

从文档:

Apollo Client 有一个可插拔的网络接口层,它可以让你配置如何通过 HTTP 发送查询

阅读有关Apollo Link、网络链接和中间件概念的更多信息

优点

  • 任何 graphql 操作都可以使用中间件的逻辑(您设置条件)
  • 您的查询不需要“关心”或了解 HTTP 标头
  • 在决定是否以及向请求添加哪些标头之前,您可以进行更多处理。
  • 还有更多..

设置上下文

与快速简便的解决方案相同,只是这次我们不直接设置headers

 {
   options: { 
     context: { 
       canHazPancakes: true //this will not reach the server
     }
   }
 }

添加中间件

Apollo 有一个特定的中间件来设置上下文apollo-link-context (同样可以用更通用的中间件来实现)。

import {setContext} from 'apollo-link-context'

//... 

const pancakesLink = setContext((operation, previousContext) => { 
  const { headers, canHazPancakes } = previousContext
  if (!canHazPancakes) { 
    return previousContext
  }

  return {
    ...previousContext,
    headers: {    
      ...headers,
      "x-with-pancakes": "yes" //your custom header
    }
  }
})

不要忘记在你的 http 链接之前将它连接到网络链的某个地方

const client = new ApolloClient({
  // ...
  link: ApolloLink.from([
    pancakesLink,
    <yourHttpLink>
  ])
})

文档中还有另一个有用的示例: 使用中间件进行身份验证

就是这样! 您现在应该从服务器获取一些煎饼。 希望这会有所帮助。

Tal Z 的回答非常好。 但是,我想我只是粘贴如何实现他为使用 Angular 的人列出的两种方法。

为每个单独的 apollo 调用添加标头

import { Component, OnInit } from '@angular/core';
import { LocalStorageService } from 'angular-2-local-storage';
import { Apollo } from 'apollo-angular';
import gql from 'graphql-tag';
import { Pineapples, Pineapple } from './models/pineapples';

export class AppComponent {

  constructor(private apollo: Apollo,
    private localStorageService: LocalStorageService) {
  }

  callGraphQLQuery() {

    const token = this.localStorageService.get('loginToken');
    this.apollo
      .watchQuery<Pineapples>({

        query: gql`
        {
          pineapples{
            id
            name
          }
        }
      `, 
       context: {
           headers: new HttpHeaders().set("Authorization", "Bearer " + token),
         }
      })
      .valueChanges.subscribe(result => {
        // handle results here
      });


  }

}

在中间件中添加标头

const uri = 'https://localhost:5001/graphql'; 

export function createApollo(httpLink: HttpLink, localStorage: LocalStorageService) {

  const http = httpLink.create({ uri });

  const authLink = new ApolloLink((operation, forward) => {
    // Get the authentication token from local storage if it exists
    const token = localStorage.get('loginToken');

    // Use the setContext method to set the HTTP headers.
    operation.setContext({
      headers: {
        'Authorization': token ? `Bearer ${token}` : ''
      }
    });

    // Call the next link in the middleware chain.
    return forward(operation);
  });

  return {
    link: authLink.concat(http),
    cache: new InMemoryCache()
  };
}

@NgModule({
  exports: [ApolloModule, HttpLinkModule],
  providers: [
    {
      provide: APOLLO_OPTIONS,
      useFactory: createApollo,
      deps: [HttpLink, LocalStorageService],
    },
  ],
})
export class GraphQLModule {}

按照 Diskdrive 的步骤,我将对 nextjs 的 getServerSideProps 做同样的事情

 export async function getServerSideProps(context) { const cookies = context.req.headers.cookie; const token = getCookie("tokenId", cookies); const { data } = await client2.query({ query: gql` query { me { firstName sureName } } `, context: { headers: { authorization: token, }, }, }); return { props: { dataFromServer: data, }, }; }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM