Skip to content

Improvements to AS3 docs that are not related to differences from AS2 #5340

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 14 commits into from
Jul 9, 2021
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion docs/source/performance/caching.md
Original file line number Diff line number Diff line change
Expand Up @@ -308,7 +308,10 @@ If you run Apollo Server behind a CDN or another caching proxy, you can configur

Because CDNs and caching proxies only cache GET requests (not POST requests, which Apollo Client sends for all operations by default), we recommend enabling [automatic persisted queries](./apq/) and the [`useGETForHashedQueries` option](./apq/) in Apollo Client.

Alternatively, you can set the `useGETForQueries` option of [HttpLink](https://www.apollographql.com/docs/react/api/link/apollo-link-http) in your `ApolloClient` instance, but **this may be less secure** because your query string and GraphQL variables are sent as plaintext URL query parameters which are more likely to be saved in logs by some server or proxy between the user and your GraphQL server. FIXME I tried to improve this but it still doesn't make that much sense because `useGETForHashedQueries` certainly puts variables in the URL... I think the real reason to avoid useGETForQueries is that GETs have a length limit!
Alternatively, you can set the `useGETForQueries` option of [HttpLink](https://www.apollographql.com/docs/react/api/link/apollo-link-http) in your `ApolloClient` instance. However, this has the following disadvantages:

* Your query string is sent as a plaintext URL query parameter, which might be saved in logs by intermediary systems (e.g., a CDN or proxy) between the client and server.
* Most browsers enforce a size limit on `GET` requests, and large query strings might exceed this limit.

## Disabling cache control

Expand Down
19 changes: 6 additions & 13 deletions docs/source/proxy-configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,15 @@ title: Proxy configuration
description: Configuring proxy settings for outgoing requests
---

Certain features of the Apollo platform require Apollo Server to make outgoing requests to Apollo Studio. These include:
Certain features of the Apollo platform (such as [managed federation](https://www.apollographql.com/docs/federation/managed-federation/overview/)) require Apollo Server to make outgoing requests to Apollo Studio. Depending on security policies, you might need to configure an outgoing HTTP proxy in order to allow these requests.

FIXME: could mention usage reporting and schema reporting too, though for them should just override fetcher...
Although Apollo Server supports standard Node.js "agent" configuration via [`https.globalAgent`](https://nodejs.org/api/https.html#https_https_globalagent) and [`http.globalAgent`](https://nodejs.org/api/http.html#http_http_globalagent) directly, we recommend using the [`global-agent`](https://github.com/gajus/global-agent#global-agent) package to reduce the amount of necessary configuration involved with [creating a custom agent](https://nodejs.org/api/http.html#http_class_http_agent).

* Managed federation
* Operation registry

Depending on security policies, you might need to configure an outgoing HTTP proxy in order to allow these requests.

While Apollo Server supports standard Node.js "agent" configuration via [`https.globalAgent`](https://nodejs.org/api/https.html#https_https_globalagent) and [`http.globalAgent`](https://nodejs.org/api/http.html#http_http_globalagent) directly, we recommend using the [`global-agent`](https://github.com/gajus/global-agent#global-agent) package to reduce the amount of necessary configuration involved with [creating a custom agent](https://nodejs.org/api/http.html#http_class_http_agent).

The `global-agent` package allows support for the common technique of setting proxy settings using environment variables (e.g. `HTTP_PROXY`, `NO_AGENT`, etc.), which is not supported by Node.js itself (and [may never be](https://github.com/nodejs/node/issues/15620)).
The `global-agent` package enables the common technique of setting proxy settings using environment variables (e.g. `HTTP_PROXY`, `NO_AGENT`, etc.), which is not supported by Node.js itself (and [may never be](https://github.com/nodejs/node/issues/15620)).

## Configuring the proxy agent

This guide covers the `global-agent` package which is supported by Node.js versions v10 and higher. When using Node.js versions _prior_ to v10, consider using the [`global-tunnel-ng`](https://github.com/np-maintain/global-tunnel) which behaves similarly, but is configured differently.
This guide covers the `global-agent` package, which is supported by Node.js version 10 and later.

### Installing the `global-agent` dependency

Expand Down Expand Up @@ -100,6 +93,6 @@ This can be done [via Node.js' `NODE_EXTRA_CA_CERTS` environment variable](https

```shell
$ NODE_EXTRA_CA_CERTS=/full/path/to/certificate.pem \
GLOBAL_AGENT_HTTP_PROXY=http://proxy:3128/ \
node index.js
GLOBAL_AGENT_HTTP_PROXY=http://proxy:3128/ \
node index.js
```
63 changes: 30 additions & 33 deletions docs/source/schema/schema.md
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ type Author {

### The `Query` type

The `Query` type is a special object type that defines all of the top-level **entry points** for queries that clients execute against your data graph.
The `Query` type is a special object type that defines all of the top-level **entry points** for queries that clients execute against your server.

Each field of the `Query` type defines the name and return type of a different entry point. The `Query` type for our example schema might resemble the following:

Expand Down Expand Up @@ -263,7 +263,7 @@ As with queries, our server would respond to this mutation with a result that ma
}
```

A single mutation operation can include multiple top-level fields of the `Mutation` type. This usually means that the operation will execute multiple back-end writes (at least one for each field). To prevent race conditions, top-level `Mutation` fields are resolved serially in the order they're listed.
A single mutation operation can include multiple top-level fields of the `Mutation` type. This usually means that the operation will execute multiple back-end writes (at least one for each field). To prevent race conditions, top-level `Mutation` fields are [resolved](../data/resolvers/) serially in the order they're listed (top-level `Query` fields can be resolved in parallel).

[Learn more about designing mutations](#designing-mutations)

Expand All @@ -273,51 +273,49 @@ See [Subscriptions](../data/subscriptions).

### Input types

Input types are special object types that allow you to pass objects as arguments to queries and mutations (as opposed to passing only scalar types). Input types help keep operation signatures clean, much like how accepting a single `options` object in a JavaScript function can be cleaner than repeatedly adding arguments to the function's signature.
Input types are special object types that allow you to provide hierarchical data as **arguments** to fields (as opposed to providing only flat scalar arguments).

Consider this mutation that creates a blog post:
An input type's definition is similar to an object type's, but it uses the `input` keyword:

```graphql
type Mutation {
createPost(title: String, body: String, mediaUrls: [String]): Post
input BlogPostContent {
title: String
body: String
}
```

Instead of accepting three arguments, this mutation could accept a _single_ input type that includes all of these fields. This comes in extra handy if we decide to accept an additional argument in the future, such as an `author`.
FIXME I don't think this is a really compelling argument, because in GraphQL all arguments are given by explicit name and argument order is igonred. So the analogy to JS (made in the previous paragraph) doesn't really hold up since "pass args by keyword" is how it already works! To me, the main reasons for input objects are (a) if you want to reuse a set of arguments in multiple fields or (b) if the arguments naturally have a more deeply nested structure. The example here doesn't show either of those.

An input type's definition is similar to an object type's, but it uses the `input` keyword:
Each field of an input type can be only a [scalar](#scalar-types), an [enum](#enum-types), or _another_ input type:

```graphql
type Mutation {
createPost(post: PostAndMediaInput): Post
}

input PostAndMediaInput {
input BlogPostContent {
title: String
body: String
mediaUrls: [String]
media: [MediaDetails!]
}

input MediaDetails {
format: MediaFormat!
url: String!
}

enum MediaFormat {
IMAGE
VIDEO
}
```

Not only does this facilitate passing the `PostAndMediaInput` type around within our schema, it also provides a basis for annotating fields with descriptions that are automatically exposed by GraphQL-enabled tools:
FIXME this is also not a super compelling argument for input objects because field arguments can have descriptions (there's even an example of that below)
After you define an input type, any number of different object fields can accept that type as an argument:

```graphql
input PostAndMediaInput {
"A main title for the post"
title: String
"The text body of the post."
body: String
"A list of URLs to render in the post."
mediaUrls: [String]
type Mutation {
createBlogPost(content: BlogPostContent!): Post
updateBlogPost(id: ID!, content: BlogPostContent!): Post
}
```

Input types can sometimes be useful when multiple operations require the exact same set of information, but you should reuse them sparingly. Operations might eventually diverge in their sets of required arguments.

> **Do not use the same input type for both queries and mutations**. In many cases, arguments that are _required_ for a mutation are _optional_ for a corresponding query.
FIXME this seems unnecessarily strong? maybe more just like "think carefully about whether fields on input types should be nullable or not"? Also we haven't mentioned nullability or optionality at all yet so that seems like it might be confusing.
> **Take care if using the same input type for fields of both `Query` and `Mutation`**. In many cases, arguments that are _required_ for a mutation are _optional_ for a corresponding query. You might want to create separate input types for each operation type.

### Enum types

Expand Down Expand Up @@ -404,10 +402,9 @@ Most _additive_ changes to a schema are safe and backward compatible. However, c

A graph management tool such as [Apollo Studio](https://studio.apollographql.com/) helps you understand whether a potential schema change will impact any of your active clients. Studio also provides field-level performance metrics, schema history tracking, and advanced security via operation safelisting.

## Documentation strings
## Descriptions (docstrings)

FIXME These are actually called "descriptions" in the GraphQL spec (we use the term above). If we want to call them doc strings that might be OK but we should at least also use the official term?
GraphQL's schema definition language (SDL) supports Markdown-enabled documentation strings. These help consumers of your data graph discover fields and learn how to use them.
GraphQL's schema definition language (SDL) supports Markdown-enabled documentation strings, called **descriptions**. These help consumers of your data graph discover fields and learn how to use them.

The following snippet shows how to use both single-line string literals and multi-line blocks:

Expand Down Expand Up @@ -547,9 +544,9 @@ A single mutation can modify multiple types, or multiple instances of the _same_

Additionally, mutations are much more likely than queries to cause errors, because they modify data. A mutation might even result in a _partial_ error, in which it successfully modifies one piece of data and fails to modify another. Regardless of the type of error, it's important that the error is communicated back to the client in a consistent way.

To help resolve both of these concerns, we recommend defining a `MutationResponse` interface in your schema, along with a collection of object types that _implement_ that interface (one for each of your mutations). FIXME this is the first reference to interfaces in the docs (other than a brief link to the interfaces page), should we at least add a link to the interfaces page? (Also the first use of non-nullable types, without explanation.)
To help resolve both of these concerns, we recommend defining a `MutationResponse` [interface](../schema/unions-interfaces/#interface-type) in your schema, along with a collection of object types that _implement_ that interface (one for each of your mutations).

Here's what the `MutationResponse` interface looks like:
Here's what a `MutationResponse` interface might look like:

```graphql
interface MutationResponse {
Expand All @@ -559,7 +556,7 @@ interface MutationResponse {
}
```

And here's what an implementing object type looks like:
And here's what an object that _implements_ `MutationResponse` might look like:

```graphql
type UpdateUserEmailMutationResponse implements MutationResponse {
Expand Down
2 changes: 0 additions & 2 deletions docs/source/security/terminating-ssl.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@
title: Terminating SSL
---

FIXME not super clear why we need this file rather than just linking to somebody else's docs about how to add https to an arbitrary Express app

Most production environments use a load balancer or HTTP proxy (such as nginx) to perform SSL termination on behalf of web applications in that environment.

If you're using Apollo Server in an application that must perform its _own_ SSL termination, you can use the `https` module with the `apollo-server-express` [middleware
Expand Down