Добавить пользовательский заголовок в запрос опроса клиента apollo

Я использую библиотеку apollo-client для запроса данных с моего сервера Graphql. некоторые запросы отправляются на сервер каждые 5 секунд благодаря возможности опроса Apollo.

Есть общий способ добавить пользовательский заголовок ко всем запросам, отправленным опросом от моего клиента?

Ответ 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  
  }
})

Общее решение с использованием промежуточного программного обеспечения Network Link

С помощью Apollo вы можете добавить Apollo Link, который будет действовать как промежуточное программное обеспечение и добавить настраиваемый заголовок для запроса на основе context который был задан вашей операцией запроса.

Из документов:

Apollo Client имеет подключаемый уровень сетевого интерфейса, который позволяет настроить способ отправки запросов по HTTP

Узнайте больше об Apollo Link, сетевом интерфейсе и концепциях промежуточного ПО.

Преимущества:

  • Логика промежуточного программного обеспечения может использоваться любой графикой (вы устанавливаете условие)
  • Ваши запросы не нужно "заботиться" или знать о заголовках 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>
  ])
})

В документах есть еще один полезный пример: использование промежуточного программного обеспечения для аутентификации.

Это! Теперь вы должны получить блины с сервера. Надеюсь это поможет.

Ответ 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 {}