Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to define the HTTP headers for the GraphQL Playground that comes with Apollo Server?

I want to define some http headers for the GraphQL Playground, to be enabled by default and/or always. Essentially, I want to add:

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

to be able to distinguish requests from the playground from any other requests on Apollo Studio. What's the best way?

By GraphQL Playground I refer to the one run by Apollo, the one documented here: https://www.apollographql.com/docs/apollo-server/testing/graphql-playground/

My current ApolloServer config looks something like this:

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

If I add tabs to it in an attempt to define the headers, like this:

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

the GraphQL playground no longer restores all tabs with their queries when reloading the page, which is very useful. I think there's some automatic tab management that gets removed as soon as you define tabs. I'm happy to have default headers defined for new tab creation, it's ok if those headers are exposed to the client.

My app already defines header, so, I can differentiate between the app and anything else that queries it, but I want to differentiate between my app, playground and anything else (the latter group should be empty).

like image 997
pupeno Avatar asked Jul 12 '20 09:07

pupeno


People also ask

How do you set HTTP headers in GraphQL playground?

Unlike GraphiQL, GraphQL Playground allows you to send requests with HTTP headers, such as a token needed to authenticate a user or some other kind of authorization. Make sure to first switch the tab to “HTTP HEADERS,” and then add your headers as a JSON object. By the way, you can add more than one field.

Which HTTP method does GraphQL support?

GraphQL requests can be sent via HTTP POST or HTTP GET requests. GET requests must be sent in the following format. The query, variables, and operation are sent as URL-encoded query parameters in the URL. In either request method (POST or GET), only query is required.

How are HTTP requests sent by Apollo Client authenticated?

Apollo Client uses HttpLink to send GraphQL operations to a server over HTTP. The link supports both POST and GET requests, and it can modify HTTP options on a per-query basis. This comes in handy when implementing authentication, persisted queries, dynamic URIs, and other granular updates.


1 Answers

Update:

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

use the GraphQL Playground Express middleware directly [...] This would allow you to leverage the Express middleware req object, and set headers accordingly.

Here is a working example:

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}`))

After page reload all tabs with their content are restored.


Answer to the original question:

It's not totally clear what you mean by Apollo Server GraphQL Playground. And what's your use case.

There is a desktop app, a web app, you can include GraphQL Playground as a module into your frontend, or as a middleware for your backend.

For the simplest case: switch to the "HTTP HEADERS" tab, add headers as JSON:

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

enter image description here

For the case of frontend Playground you can pass tabs with headers property to <Playground/>:

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

For backend, you can use headers as well:

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

You can also

distinguish requests from the playground from requests from the actual apps

by going the opposite way: add extra headers to you actual apps.

like image 186
x00 Avatar answered Oct 24 '22 05:10

x00