Javascript 向apollo客户端轮询请求添加自定义标头

Javascript 向apollo客户端轮询请求添加自定义标头,javascript,graphql,apollo,apollo-client,graphql-js,Javascript,Graphql,Apollo,Apollo Client,Graphql Js,我正在使用apollo客户端库从我的Graphql服务器查询数据。一些查询通过apollo轮询功能每5秒发送到服务器 是否有一种通用方法可以将自定义头添加到轮询客户端发送的所有请求中?两种解决方案 有两种方法可以做到这一点。一种是快速简便的,可用于具有某些限制的特定查询;另一种是通用解决方案,更安全,可用于多个查询 快速简便的解决方案 优势 很快 而且。。。轻松的 配置查询时,可以使用其选项字段对其进行配置,该字段具有上下文字段。context的值将由网络链处理。上下文本身不会发送到服务器,

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

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

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

快速简便的解决方案 优势

  • 很快
  • 而且。。。轻松的
配置查询时,可以使用其
选项
字段对其进行配置,该字段具有
上下文
字段。
context
的值将由网络链处理。
上下文
本身不会发送到服务器,但如果向其添加
字段,则它将在HTTP请求中使用

示例

const someQuery = graphql(gql`query { ... }`, {
  options: { 
    context: { 
      headers: { 
        "x-custom-header": "pancakes"  // this header will reach the server
      } 
    },
    // ... other options  
  }
})
使用网络链接中间件的通用解决方案 使用Apollo,您可以添加Apollo链接,该链接将充当中间件,并根据查询操作设置的
上下文向请求添加自定义头

从文档中:

Apollo客户端有一个可插拔的网络接口层,可以让 您可以配置如何通过HTTP发送查询

阅读更多关于

优势

const someQuery = graphql(gql`query { ... }`, {
  options: { 
    context: { 
      headers: { 
        "x-custom-header": "pancakes"  // this header will reach the server
      } 
    },
    // ... other options  
  }
})
  • 中间件的逻辑可以被任何graphql操作使用(您可以设置条件)
  • 您的查询不需要“关心”或了解HTTP头
  • 在决定是否以及向请求中添加哪些头之前,可以进行更多的处理
  • 还有更多
设置上下文

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

 {
   options: { 
     context: { 
       canHazPancakes: true //this will not reach the server
     }
   }
 }
添加中间件

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 {}
Apollo有一个特定的中间件,用于设置上下文
Apollo链接上下文
(使用更通用的中间件也可以实现这一点)

不要忘记在http链接之前将其连接到网络链的某个位置

const client = new ApolloClient({
  // ...
  link: ApolloLink.from([
    pancakesLink,
    <yourHttpLink>
  ])
})
const客户端=新客户端({
// ...
链接:ApolloLink.from([
煎饼店,
])
})
文档中还有另一个有用的示例:


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

Tal Z的答案很好。然而,我想我应该粘贴如何实现他为使用Angular的人列出的两种方法

为每个阿波罗呼叫添加标题

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
      });


  }

}

我删除了我的答案,以便其他人认为这是未回答的。好的,但是如果应用程序已经初始化并且客户端已经创建,如何设置上下文?这也是我的问题。中间件似乎不支持动态头。。。但愿我错了?另外,我将如何在一个组件中实现这一点?您能否提供快速简便解决方案的文档链接?我无法让它工作。嗨,请注意快速简单的解决方案-我不需要选项属性-只有上下文和下面的内容对我有效为什么在localstorage中设置cookie?