6

我想为 GraphQL Playground 定义一些 http 标头,默认启用和/或始终启用。本质上,我想补充:

"apollographql-client-name": "playground"
"apollographql-client-version": "yada-yada"

能够将来自操场的请求与 Apollo Studio 上的任何其他请求区分开来。最好的方法是什么?

通过 GraphQL Playground,我指的是 Apollo 运行的那个,这里记录的那个:https ://www.apollographql.com/docs/apollo-server/testing/graphql-playground/

我当前的 ApolloServer 配置如下所示:

let apolloServerExpressConfig: ApolloServerExpressConfig = {
  schema: schema,
  playground: {
    settings: {
      "request.credentials": "include",
    },
  },
}

如果我添加标签以尝试定义标题,如下所示:

let apolloServerExpressConfig: ApolloServerExpressConfig = {
  schema: schema,
  playground: {
    settings: {
      "request.credentials": "include",
    },
    tabs: [{
      headers: {
        "apollographql-client-name": "playground",
        "apollographql-client-version": "yada-yada",
      },
    }],
  },
}

重新加载页面时,GraphQL 游乐场不再恢复所有选项卡及其查询,这非常有用。我认为一旦您定义了选项卡,就会删除一些自动选项卡管理。我很高兴为新选项卡创建定义了默认标题,如果这些标题暴露给客户端就可以了。

我的应用程序已经定义了标题,因此,我可以区分应用程序和查询它的任何其他内容,但我想区分我的应用程序、游乐场和其他任何内容(后一组应该为空)。

4

2 回答 2

5

更新:

https://github.com/apollographql/apollo-server/issues/1982#issuecomment-511765175

直接使用GraphQL Playground Express 中间件[...] 这将允许您利用Express中间件req对象,并相应地设置标题。

这是一个工作示例:

const app                   = require('express')()
const { ApolloServer, gql } = require('apollo-server-express')

// use this directly
  const expressPlayground   = require('graphql-playground-middleware-express').default

// just some boilerplate to make it runnable
  const typeDefs = gql`type Book { title: String author: String } type Query { books: [Book] }`
  const books = [{ title: 'Harry Potter and the Chamber of Secrets', author: 'J.K. Rowling' }, { title: 'Jurassic Park', author: 'Michael Crichton' }]
  const resolvers = { Query: { books: () => books } }
  const server = new ApolloServer({ typeDefs, resolvers });

//
// the key part {
//
  const headers = JSON.stringify({
    "apollographql-client-name"   : "playground",
    "apollographql-client-version": "yada-yada" ,
  })
  app.get('/graphql', expressPlayground({
    endpoint: `/graphql?headers=${encodeURIComponent(headers)}`,
  }))
  server.applyMiddleware({ app })

//
// }
//

// just some boilerplate to make it runnable
app.listen({ port: 4000 }, () => console.log(` Server ready at http://localhost:4000${server.graphqlPath}`))

页面重新加载后,所有选项卡及其内容都会恢复。


回答原来的问题:

您所说的Apollo Server GraphQL Playground是什么意思并不完全清楚。你的用例是什么。

有一个桌面应用程序,一个网络应用程序,您可以将GraphQL Playground作为一个模块包含到您的前端,或者作为您的后端的中间件。

对于最简单的情况:切换到“HTTP HEADERS”选项卡,将标头添加为 JSON:

{
  "apollographql-client-name": "playground",
  "apollographql-client-version": "yada-yada",
}

在此处输入图像描述

对于前端Playground,您可以将属性传递tabs给:headers<Playground/>

<Playground
  ...
  tabs={[{
    name: 'Tab 1',
    headers: {
      "apollographql-client-name"   : "playground",
      "apollographql-client-version": "yada-yada" ,
    }
    ...
  }]}
/>,

对于后端,您也可以使用headers

new ApolloServer({
  ...
  playground: {
    ...
    tabs: [{
      ...
      headers: ...
    }],
  },
})

你也可以

将来自 Playground 的请求与来自实际应用程序的请求区分开来

通过相反的方式:为您的实际应用添加额外的标题。

于 2020-07-29T17:26:43.970 回答
0

Apollo-server-plugin-http-headers

允许您在解析器中轻松设置 HTTP 标头和 Cookie。这在 apollo-server-lambda 中特别有用,因为您没有任何其他选项可以设置标头或 cookie。

它的工作方式很简单:在上下文中放置一个 cookie 数组和一个 header 数组;然后,您可以在解析器中访问它们(因此添加、更改或删除标头和 cookie)。在您的请求发送到客户端之前,此插件会遍历数组并将每个项目添加到 HTTP 响应中。逻辑很简单,实际上文档比源代码长得多。

用法 - 标题

在解析器中设置标题:

context.setHeaders.push({ key: "headername", value: "headercontent" });

完整示例:

const resolvers = {
    Query: {
        hello: async (parent, args, context, info) => {
            context.setHeaders.push({ key: "X-TEST-ONE", value: "abc" });
            context.setHeaders.push({ key: "X-TEST-TWO", value: "def" });
            return "Hello world!";
        }
    }
};
于 2020-07-31T11:20:24.943 回答