J'utilise apollo-client
bibliothèque pour interroger les données de mon Graphql
serveur. certaines des requêtes sont envoyées au serveur toutes les 5 secondes grâce à la capacité d'interrogation apollo.
Il existe un moyen générique d'ajouter un en-tête personnalisé à toutes les demandes envoyées par l'interrogation de mon client?
Il y a deux façons de procéder. L'un est rapide et facile et fonctionnera pour une requête spécifique avec certaines limitations, et l'autre est une solution générale qui est plus sûr et peut fonctionner pour plusieurs requêtes.
Avantages
Lorsque vous configurez votre requête, vous pouvez la configurer à l'aide de son champ options
, qui possède un champ context
. La valeur de context
sera traitée par la chaîne réseau. Le context
lui-même n'est pas envoyé au serveur, mais si vous lui ajoutez un champ headers
, il sera utilisé dans la requête HTTP.
Exemple :
const someQuery = graphql(gql`query { ... }`, {
options: {
context: {
headers: {
"x-custom-header: "pancakes" // this header will reach the server
}
},
// ... other options
}
})
Avec Apollo, vous pouvez ajouter un lien Apollo qui agira comme un middleware et ajouter un en-tête personnalisé à la demande en fonction du context
qui a été défini par votre opération de requête.
De la documentation:
Apollo Client possède une couche d'interface réseau enfichable, qui peut vous permettre de configurer la façon dont les requêtes sont envoyées via HTTP
En savoir plus sur Apollo Link, le lien réseau et les concepts de middleware .
Avantages :
Définition du contexte
Identique à la solution rapide et facile, mais cette fois, nous ne définissons pas directement le headers
:
options: {
context: {
canHazPancakes: true //this will not reach the server
}
}
Ajout du middleware
Apollo dispose d'un middleware spécifique pour définir le contexte apollo-link-context
(la même chose peut être obtenue avec un middleware plus général).
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
}
}
})
N'oubliez pas de le concaténer à la chaîne du réseau quelque part avant votre lien http
const client = new ApolloClient({
// ...
link: ApolloLink.from([
pancakesLink,
<yourHttpLink>
])
})
Il existe un autre exemple utile dans la documentation: en utilisant un middleware pour l'authentification .
C'est tout! Vous devriez obtenir des crêpes du serveur maintenant. J'espère que cela t'aides.
La réponse de Tal Z est très bonne. Cependant, je pensais simplement coller comment implémenter les deux méthodes qu'il a répertoriées pour ceux qui utilisent Angular.
Ajout de l'en-tête pour chaque appel apollo individuel
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
});
}
}
Ajout de l'en-tête dans le 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 {}