diff --git a/CHANGELOG.md b/CHANGELOG.md index 3eb76147e08..9c27ab023c0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,7 +11,7 @@ The version headers in this history reflect the versions of Apollo Server itself > The changes noted within this `vNEXT` section have not been released yet. New PRs and commits which introduce changes should include an entry in this `vNEXT` section as part of their development. With few exceptions, the format of the entry should follow convention (i.e., prefix with package name, use markdown `backtick formatting` for package names and code, suffix with a link to the change-set à la `[PR #YYY](https://link/pull/YYY)`, etc.). When a release is being prepared, a new header will be (manually) created below and the appropriate changes within that release will be moved into the new section. -- Improve startup error handling by ensuring that your server has loaded its schema and executed its `serverWillStart` handlers successfully before starting an HTTP server. If you're using the `apollo-server` package, no code changes are necessary. If you're using an integration such as `apollo-server-express` that is not a "serverless framework", you can should insert [`await server.start()`](https://www.apollographql.com/docs/apollo-server/api/apollo-server/#start) between `server = new ApolloServer()` and `server.applyMiddleware`. (If you don't call `server.start()` yourself, your server will still work, but the previous behavior of starting a web server that may fail to load its schema still applies.) The serverless framework integrations (Lambda, Azure Functions, and Cloud Functions) do not support this functionality. The protected method `willStart` has been removed; `start` or the new protected method `ensureStarting` should fulfill the same purpose if you were using it. [PR #4981](https://github.com/apollographql/apollo-server/pull/4981) +- Improve startup error handling by ensuring that your server has loaded its schema and executed its `serverWillStart` handlers successfully before starting an HTTP server. If you're using the `apollo-server` package, no code changes are necessary. If you're using an integration such as `apollo-server-express` that is not a "serverless framework", you can insert [`await server.start()`](https://www.apollographql.com/docs/apollo-server/api/apollo-server/#start) between `server = new ApolloServer()` and `server.applyMiddleware`. (If you don't call `server.start()` yourself, your server will still work, but the previous behavior of starting a web server that may fail to load its schema still applies.) The serverless framework integrations (Lambda, Azure Functions, and Cloud Functions) do not support this functionality. The protected method `willStart` has been removed; `start` or the new protected method `ensureStarting` should fulfill the same purpose if you were using it. [PR #4981](https://github.com/apollographql/apollo-server/pull/4981) ## v2.21.2 diff --git a/docs/source/api/apollo-server.md b/docs/source/api/apollo-server.md index 32d96d793d1..e8f20f45ca2 100644 --- a/docs/source/api/apollo-server.md +++ b/docs/source/api/apollo-server.md @@ -617,7 +617,7 @@ A lifecycle hook that's called whenever a subscription connection is terminated #### `listen` -> This method is provided only by the `apollo-server` package. If you're integrating with Node.js middleware via a different package (such as `apollo-server-express`), instead see [`applyMiddleware`](#applymiddleware). +> This method is provided only by the `apollo-server` package. If you're integrating with Node.js middleware via a different package (such as `apollo-server-express`), instead see both [`start`](#start) and [`applyMiddleware`](#applymiddleware). Instructs Apollo Server to begin listening for incoming requests: @@ -699,26 +699,33 @@ The full URL of the server's subscriptions endpoint. #### `start` -`ApolloServer.start()` is an async method that tells your Apollo Server to do everything necessary to prepare to serve traffic. +The async `start` method instructs Apollo Server to prepare to handle incoming operations. -You should not call this if you are using the `apollo-server` package; that package's [`listen`](#listen) method begins by starting the server for you. +> Call `start` **only** if you are using a [middleware integration](../integrations/middleware/) for a non-"serverless" environment (e.g., `apollo-server-express`). +> +> * If you're using the core `apollo-server` library, call [`listen`](#listen) instead. +> * If you're using a "serverless" middleware integration (such as `apollo-server-lambda`), this method isn't necessary because the integration doesn't distinguish between starting the server and serving a request. -You should not call this if you are using `apollo-server-lambda`, `apollo-server-azure-functions`, or `apollo-server-cloud-functions`; these "serverless" framework integrations don't differentiate between "starting the server" and "serving a request". +Always call `await server.start()` *before* calling `server.applyMiddleware` and starting your HTTP server. This allows you to react to Apollo Server startup failures by crashing your process instead of starting to serve traffic. -You *should* call this if you are using another integration package such as `apollo-server-express`. Specifically, you should call `await server.start()` *before* calling `server.applyMiddleware` and starting your HTTP server. This will allow you to react to Apollo Server startup failures by crashing your process rather than starting to serve traffic. +##### Triggered actions -Starting your server consists of two steps. +The `start` method triggers the following actions: -First, if your server is a [federated gateway](https://www.apollographql.com/docs/federation/managed-federation/overview/), it loads its schema; if it cannot load the schema, `start()` throws. +1. If your server is a [federated gateway](https://www.apollographql.com/docs/federation/managed-federation/overview/), it attempts to fetch its schema. If the fetch fails, `start` throws an error. +2. Your server calls all of the [`serverWillStart` handlers](../integrations/plugins/#serverwillstart) of your installed plugins. If any of these handlers throw an error, `start` throws an error. -Second, all [plugin `serverWillStart` handlers](../integrations/plugins/#serverwillstart) are invoked in parallel; if any of these throw, `start()` throws. +##### Backward compatibility + +To ensure backward compatibility, calling `await server.start()` is optional. If you don't call it yourself, your integration package invokes it when you call `server.applyMiddleware`. Incoming GraphQL operations wait to execute until Apollo Server has started, and those operations fail if startup fails (a redacted error message is sent to the GraphQL client). + +We recommend calling `await server.start()` yourself, so that your web server doesn't start accepting GraphQL requests until Apollo Server is ready to process them. -For backwards compatibility reasons, calling `await server.start()` is optional. If you don't call it yourself, your integration package will invoke it "in the background" when you call `server.applyMiddleware`, and any attempt to execute a GraphQL operation will wait until the server has started and fail if startup fails (with a redacted error message sent to the GraphQL client). We recommend calling it yourself, so that your web server doesn't start trying to serve traffic until the Apollo Server is capable of accepting it. #### `applyMiddleware` Connects Apollo Server to the HTTP framework of a Node.js middleware library, such as hapi or express. -You call this method instead of [`listen`](#listen) if you're using an `apollo-server-{integration}` package. You are highly recommended to [`await server.start()`](#start) before calling this method. +You call this method instead of [`listen`](#listen) if you're using a [middleware integration](../integrations/middleware/), such as `apollo-server-express`. You should call [`await server.start()`](#start) _before_ calling this method. Takes an `options` object as a parameter. Supported fields of this object are described below. diff --git a/docs/source/data/subscriptions.mdx b/docs/source/data/subscriptions.mdx index 49109b617b7..4307e7e1094 100644 --- a/docs/source/data/subscriptions.mdx +++ b/docs/source/data/subscriptions.mdx @@ -411,7 +411,6 @@ In case of an authentication error, the Promise will be rejected, which prevents You can use subscriptions with any of Apollo Server's supported [middleware integrations](../integrations/middleware/). To do so, you call `installSubscriptionHandlers` on your `ApolloServer` instance. - This example enables subscriptions for an Express server that uses `apollo-server-express`: ```js