添加自定义 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
}
})
使用网络 Link 中间件的一般解决方案
使用 Apollo,您可以添加一个 Apollo Link 作为中间件,并根据您的查询操作设置的 context
向请求添加自定义 header .
来自文档:
Apollo Client has a pluggable network interface layer, which can let
you configure how queries are sent over HTTP
详细了解 Apollo Link, the network link and Middleware concepts。
优势:
- 任何graphql操作都可以使用中间件的逻辑(你设置条件)
- 您的查询不需要 "care" 或知道 HTTP headers
- 您可以在决定是否将 header 添加到请求中以及添加什么之前进行更多处理。
- 等等..
设置上下文
与快速简便的解决方案相同,只是这次我们不直接设置 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 link
之前某处的网络链
const client = new ApolloClient({
// ...
link: ApolloLink.from([
pancakesLink,
<yourHttpLink>
])
})
文档中还有另一个有用的示例:using a middleware for authentication。
就这样了!你现在应该从服务器上拿些煎饼来。希望这会有所帮助。
Tal Z 的回答很好。但是,我想我只是粘贴如何实现他为那些使用 Angular.
的人列出的两种方法
为每个单独的 apollo 调用添加 header
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
});
}
}
在中间件中添加header
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,
},
};
}
我正在使用 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
}
})
使用网络 Link 中间件的一般解决方案
使用 Apollo,您可以添加一个 Apollo Link 作为中间件,并根据您的查询操作设置的 context
向请求添加自定义 header .
来自文档:
Apollo Client has a pluggable network interface layer, which can let you configure how queries are sent over HTTP
详细了解 Apollo Link, the network link and Middleware concepts。
优势:
- 任何graphql操作都可以使用中间件的逻辑(你设置条件)
- 您的查询不需要 "care" 或知道 HTTP headers
- 您可以在决定是否将 header 添加到请求中以及添加什么之前进行更多处理。
- 等等..
设置上下文
与快速简便的解决方案相同,只是这次我们不直接设置 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 link
之前某处的网络链const client = new ApolloClient({
// ...
link: ApolloLink.from([
pancakesLink,
<yourHttpLink>
])
})
文档中还有另一个有用的示例:using a middleware for authentication。
就这样了!你现在应该从服务器上拿些煎饼来。希望这会有所帮助。
Tal Z 的回答很好。但是,我想我只是粘贴如何实现他为那些使用 Angular.
的人列出的两种方法为每个单独的 apollo 调用添加 header
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
});
}
}
在中间件中添加header
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,
},
};
}