【问题标题】:将自定义标头添加到 apollo 客户端轮询请求
【发布时间】:2018-07-11 12:54:41
【问题描述】:

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

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

【问题讨论】:

  • 我删除了我的答案,以便其他人将其视为未答复。

标签: javascript graphql apollo apollo-client graphql-js


【解决方案1】:

两种解决方案

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

快速简便的解决方案

优势

  • 很快
  • 而且...简单

当您配置查询时,您可以使用它的 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, the network link and Middleware concepts的信息。

优势

  • 任何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>
  ])
})

文档中还有另一个有用的示例:using a middleware for authentication

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

【讨论】:

  • 好的,但是如果应用已经初始化并且ApolloClient已经创建了,如何设置上下文呢?
  • 这也是我的问题。中间件似乎没有动态标题的能力......希望我错了?另外,我将如何在 组件中实现这一点?
  • 您能否提供快速简便解决方案的文档链接?我无法让它工作。
  • 嗨,请注意快速简便的解决方案 - 我不需要 options 属性 - 只是上下文和以下内容对我有用
【解决方案2】:

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 {}

【讨论】:

  • 为什么要在localstorage中设置cookie?
猜你喜欢
  • 2016-11-14
  • 1970-01-01
  • 1970-01-01
  • 2017-12-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-11-13
  • 1970-01-01
相关资源
最近更新 更多