javascript 向 apollo 客户端轮询请求添加自定义标头
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/48558681/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Add custom header to apollo client polling request
提问by Ron Badur
I am using the apollo-clientlibrary to query data from my Graphqlserver. Some of the queries are sent to the server every 5 seconds through apollo polling ability.
我正在使用该apollo-client库从我的Graphql服务器查询数据。一些查询每 5 秒通过 apollo 轮询功能发送到服务器。
Is there a generic way to add a custom header to all requests that are sent by my polling client?
有没有一种通用的方法可以向我的轮询客户端发送的所有请求添加自定义标头?
回答by Tal Z
Two Solutions
两种解决方案
There are two ways to do that. One is quick and easyand will work for a specific query with some limitation, and the other is a general solutionthat is safer and can work for multiple queries.
有两种方法可以做到这一点。一种快速简便,适用于具有某些限制的特定查询,另一种是更安全且适用于多个查询的通用解决方案。
Quick and Easy Solution
快速简便的解决方案
Advantages
好处
- it's quick
- and... easy
- 很快
- 和...容易
When you configure your query you can configure it using its optionsfield, that has a contextfield. The value of contextwill be processed by the network chain. The contextitself is not sent to the server, but if you add a headersfield to it, it will be used in the HTTP request.
当你配置你的查询时,你可以使用它的options字段来配置它,它有一个context字段。的值context将由网络链处理。在context本身没有发送到服务器,但如果你添加一个headers字段,它会在HTTP请求中使用。
Example:
示例:
const someQuery = graphql(gql`query { ... }`, {
options: {
context: {
headers: {
"x-custom-header": "pancakes" // this header will reach the server
}
},
// ... other options
}
})
General Solution using a Network Link middleware
使用网络链接中间件的通用解决方案
With Apollo you can add an Apollo Link that will act as a middleware and add a custom header to the request based on the contextthat was set by your query operation.
使用 Apollo,您可以添加一个作为中间件的 Apollo Link,并根据context查询操作设置的向请求添加自定义标头。
From the docs:
从文档:
Apollo Client has a pluggable network interface layer, which can let you configure how queries are sent over HTTP
Apollo Client 有一个可插拔的网络接口层,它可以让你配置如何通过 HTTP 发送查询
Read more about Apollo Link, the network link and Middleware concepts.
阅读有关Apollo Link、网络链接和中间件概念的更多信息。
Advantages:
优点:
- The middleware's logic can be used by any graphql operation (you set the condition)
- Your queries don't need to "care" or know about HTTP headers
- You can do more processing before deciding if and what headers to add to the request.
- and more..
- 任何 graphql 操作都可以使用中间件的逻辑(您设置条件)
- 您的查询不需要“关心”或了解 HTTP 标头
- 在决定是否以及向请求添加哪些标头之前,您可以进行更多处理。
- 和更多..
Setting the context
设置上下文
Same as the quick and easy solution, only this time we don't set the headersdirectly:
与快速简便的解决方案相同,只是这次我们不headers直接设置:
{
options: {
context: {
canHazPancakes: true //this will not reach the server
}
}
}
Adding the middleware
添加中间件
Apollo has a specific middleware for setting the context apollo-link-context(the same can be achieved with a more general middleware).
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
}
}
})
Don't forget to concat it to the network chain somewhere before your http link
不要忘记在你的 http 链接之前将它连接到网络链的某个地方
const client = new ApolloClient({
// ...
link: ApolloLink.from([
pancakesLink,
<yourHttpLink>
])
})
There is another useful example in the docs: using a middleware for authentication.
文档中还有另一个有用的示例:使用中间件进行身份验证。
That's it!You should get some pancakes from the server now. Hope this helps.
而已!您现在应该从服务器获取一些煎饼。希望这可以帮助。
回答by Diskdrive
Tal Z's answer is very good. However, I thought I'd just paste how to implement the two methods he's listed for those using Angular.
Tal Z 的回答非常好。但是,我想我只是粘贴如何实现他为使用 Angular 的人列出的两种方法。
Adding the header for each individual apollo call
为每个单独的 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
});
}
}
Adding the header in the middleware
在中间件中添加标头
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 {}

