Skip to content

Commit

Permalink
Generalize Playground support to a simple "HTML page" plugin API
Browse files Browse the repository at this point in the history
Apollo Server has graphql-playground built in, to the degree that the
playground-html renderPlaygroundPage options are a top-level key in Apollo
Server config.

This has been very useful, but the theme of Apollo Server 3 is to keep its API
lean and disentangled from other packages. Every single Apollo Server
integration package has the same copy-and-paste code that threads playground
options directly into the playground package.

Additionally, graphql-playground has is retiring (see
graphql/graphql-playground#1143) and merging back into
GraphiQL. So it especially doesn't make sense for Apollo Server's API to
continue to be defined by Playground.

We could just switch back to GraphiQL like in Apollo Server 1, but instead,
let's move UI configuration out of the top-level ApolloServer API and move it
into our plugin system. And let's make sure that the per-web-framework
integration packages don't need to care what UI system you're using.

This PR adds a very very very simple static HTML serving API to our plugin
system. The point of this system is to support plugins that serve a bit of HTML
to load a full UI from CDN, like for Playground, GraphiQL, Explorer, etc, or to
serve a splash page linking to other UIs.

The point of this system is not to be a convenient way to add app-specific HTML
to your app. If you want to do that, just use middleware in your web framework!
The point is to make UI plugins that work out of the box with every Apollo
Server integration. Because of that, the plugins can do very little: they can
serve static HTML pages at one or more URL paths, and they can ask for a
redirect from root to one of their pages.

We add ApolloServerPluginUIGraphQLPlayground in core, as well as
ApolloServerPluginUIDisabled. Like other plugins, if you don't set some UI
plugin of your own and don't set the disabled plugin, Apollo Server will
auto-install a plugin. In this case it installs the playground plugin though we
may change that before 3.0.0.

Also:

- Tests that set environment variables (as some of the playground ones do) make
  me uncomfortable. Added `__testing__nodeEnv` to the ApolloServer and
  GraphQLOptions interfaces that can be used to test how `process.env.NODE_ENV`
  affects AS without actually changing the environment.
- Inline fastifyApollo into fastify's ApolloServer.
  • Loading branch information
glasser committed May 21, 2021
1 parent a65396f commit 9841b86
Show file tree
Hide file tree
Showing 56 changed files with 3,493 additions and 8,982 deletions.
20 changes: 1 addition & 19 deletions docs/source/api/apollo-server.md
Original file line number Diff line number Diff line change
Expand Up @@ -359,24 +359,6 @@ The default value is `10_000` (10 seconds).
</td>
</tr>

<tr>
<td>

###### `playground`

`Boolean` or `Object`
</td>
<td>

If truthy, the server hosts [GraphQL Playground](../testing/graphql-playground) from its URL. Can be an object to pass [configuration options](https://github.com/prismagraphql/graphql-playground/#usage) to the playground.

The default value is `true`, **unless** the `NODE_ENV` environment variable is set to `production`.

Note that [`introspection`](#introspection) must be enabled for GraphQL Playground to function properly.
</td>
</tr>


<tr>
<td>

Expand Down Expand Up @@ -784,7 +766,7 @@ The default value is `true`.

#### `getMiddleware`

Returns an array of the middlewares that together form a complete instance of Apollo Server. Includes middleware for HTTP body parsing, GraphQL Playground, file uploads, and subscriptions.
Returns an array of the middlewares that together form a complete instance of Apollo Server. Includes middleware for HTTP body parsing, health checks, setting CORS headers, and serving a static UI, as well as actually executing GraphQL operations.

Unlike [`applyMiddleware`](#applymiddleware), `getMiddleware` does _not_ automatically apply Apollo Server middlewares to your application. Instead, this method enables you to apply or omit individual middlewares according to your use case. For an Express or Koa application, you can apply a particular middleware by calling `app.use`.

Expand Down
2 changes: 1 addition & 1 deletion docs/source/data/subscriptions.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {ExpansionPanel} from 'gatsby-theme-apollo-docs';

> **Subscriptions are not currently supported in [Apollo Federation](https://www.apollographql.com/docs/federation/).**
**Subscriptions** are long-lasting GraphQL read operations that can update their result whenever a particular server-side event occurs. Most commonly, updated results are _pushed_ from the server to subscribing clients. For example, a chat application's server might use a subscription to push newly received messages to all clients in a particular chat room.
**Subscriptions** are long-lasting GraphQL read operations that can update their result whenever a particular server-side event occurs. Most commonly, updated results are _pushed_ from the erver to subscribing clients. For example, a chat application's server might use a subscription to push newly received messages to all clients in a particular chat room.

Because subscription updates are usually pushed by the server (instead of polled by the client), they usually use [the WebSocket protocol](https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API) instead of HTTP. To support this, Apollo Server lets you [set a subscription-specific endpoint](#setting-a-subscription-endpoint) that's separate from the default endpoint for queries and mutations.

Expand Down
1 change: 1 addition & 0 deletions docs/source/deployment/azure-functions.md
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,7 @@ Functions in apollo-example:
Finally, going to the Invoke URL shown at the output above, we will see our result.
FIXME take a look
Note: When GraphQL Playground starts, It won't have the correct URL containing the security `code`, and a message **"Server cannot be reached"** as shown at your browser.
![Apollo server running on azure with error](../images/deployment/azure-functions/apollo-server-on-azure.png)
Expand Down
1 change: 1 addition & 0 deletions docs/source/deployment/lambda.md
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,7 @@ exports.graphqlHandler = server.createHandler({

## Setting up GraphQL Playground

FIXME take a look
By default, `serverless` will deploy to AWS with the `stage` set to `development` resulting in an API endpoint at `/dev/graphql`.

To allow GraphQL Playground to correctly use the `dev` endpoint, add a new `endpoint` configuration within the `playground` option to the `ApolloServer` instantiation options:
Expand Down
1 change: 1 addition & 0 deletions docs/source/deployment/netlify.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ const server = new ApolloServer({
exports.handler = server.createHandler();
```

FIXME take a look
Now, make sure you've run `NODE_ENV=development npm run start:lambda`, and navigate to `localhost:9000/graphql` in your browser. You should see GraphQL Playground, where you can run queries against your API!

*Note - The GraphQL Playground will only run if your `NODE_ENV` is set to `development`. If you don't pass this, or your `NODE_ENV` is set to `production`, you will not see the GraphQL Playground.*
Expand Down
1 change: 1 addition & 0 deletions docs/source/getting-started.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,7 @@ We're up and running!
We can now execute GraphQL queries on our server. To execute our first query,
we can use a tool called **GraphQL Playground**.
FIXME update?
<ExpansionPanel title="📣 The Apollo Studio Explorer now supports local servers">
Expand Down
2 changes: 1 addition & 1 deletion docs/source/integrations/middleware.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,6 @@ async function startApolloServer() {

The parameter you provide to `applyMiddleware` is your middleware's top-level representation of your application. In Express applications, this variable is commonly named `app`.

When you pass your app to `applyMiddleware`, Apollo Server automatically configures various middleware (including body parsing, the GraphQL Playground frontend, and CORS support), so you don't need to apply them with a mechanism like `app.use`.
When you pass your app to `applyMiddleware`, Apollo Server automatically configures various middleware (including body parsing, an HTML UI, and CORS support), so you don't need to apply them with a mechanism like `app.use`.

> **Note:** When integrating with hapi, call `applyMiddleware` with `await`.
2 changes: 2 additions & 0 deletions docs/source/testing/graphql-playground.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ To try out dev graphs:

</ExpansionPanel>

FIXME look at this whole page

[GraphQL Playground](https://github.com/prismagraphql/graphql-playground) is a graphical, interactive, in-browser GraphQL IDE, created by [Prisma](https://www.prisma.io/) and based on [GraphiQL](https://github.com/graphql/graphiql).

In development, Apollo Server enables GraphQL Playground on the same URL as the GraphQL server itself (e.g. `http://localhost:4000/graphql`) and automatically serves the GUI to web browsers. When `NODE_ENV` is set to `production`, GraphQL Playground (as well as introspection) is disabled as a production best-practice.
Expand Down
Loading

0 comments on commit 9841b86

Please sign in to comment.