Skip to content
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

Query Planner Transitive Dependency POC #922

Draft
wants to merge 7 commits into
base: version-0.x
Choose a base branch
from
Draft
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
Prev Previous commit
Next Next commit
Merge Upstream Changes
  • Loading branch information
joshmarsh committed Jul 30, 2021
commit c9420f6f67fd5dbed16a841f4feab1c760281d22
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions docs/source/errors.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,11 @@ If Apollo Gateway encounters an error, composition fails. This document lists co
| `REQUIRES_FIELDS_MISSING_ON_BASE` | The `fields` argument of an entity field's `@requires` directive includes a field that is not defined in the entity's originating subgraph.`|
| `REQUIRES_USED_ON_BASE` | An entity field is marked with `@requires` in the entity's originating subgraph, which is invalid. |

## `@tag`
| Code | Description |
|---|---|
| `TAG_DIRECTIVE_DEFINITION_INVALID` | The `@tag` directive definition is included but defined incorrectly. Please include the correct `@tag` directive definition: `directive @tag(name: String!) repeatable on FIELD_DEFINITION`|

## Custom directives

| Code | Description |
Expand Down
26 changes: 26 additions & 0 deletions docs/source/gateway.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,32 @@ As a recommended alternative, you can use the [Rover CLI](https://www.apollograp

For an example of this, see the [Federation quickstart](./quickstart/).

## Updating the gateway

> Before updating your gateway's version, check the [changelog](https://github.com/apollographql/federation/blob/main/gateway-js/CHANGELOG.md) for potential breaking changes.
>
> We strongly recommend updating your gateway in local and test environments before deploying updates to staging or production.

You can confirm the currently installed version of the `@apollo/gateway` library with the `npm list` command:

```bash
npm list @apollo/gateway
```

To update the library, use the [`npm update`](https://docs.npmjs.com/cli/v7/commands/npm-update) command:

```bash
npm update @apollo/gateway
```

This updates the library to the most recent version allowed by your `package.json` file. [Learn more about dependency constraints.](https://docs.npmjs.com/cli/v7/commands/npm-update#example)

To update to a particular version (including a version that _exceeds_ your dependency constraints), use `npm install` instead:

```bash
npm install @apollo/[email protected]
```

## Customizing requests and responses

The gateway can modify the details of an incoming request before executing it across your subgraphs. For example, your subgraphs might all use the same authorization token to associate an incoming request with a particular user. The gateway can add that token to each operation it sends to your subgraphs.
Expand Down
6 changes: 3 additions & 3 deletions docs/source/managed-federation/setup.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -57,12 +57,12 @@ After obtaining your graph API key, you set two environment variables in your ga

```sh:title=.env
APOLLO_KEY=<YOUR_GRAPH_API_KEY>
APOLLO_SCHEMA_CONFIG_DELIVERY_ENDPOINT=https://uplink.api.apollographql.com/
APOLLO_GRAPH_REF=<YOUR_GRAPH_ID>@<VARIANT>
```

You can also set these values directly in the command you use to start your gateway.
You can also set this value directly in the command you use to start your gateway.

The second environment variable, `APOLLO_SCHEMA_CONFIG_DELIVERY_ENDPOINT`, instructs the gateway to fetch its configuration from a new (and recommended) Apollo-hosted endpoint called the **uplink**. If you don't set this value, the gateway instead fetches its configuration from a file hosted in Google Cloud Storage.
The third environment variable, `APOLLO_GRAPH_REF`, tells the gateway which graph to use and with which variant. You would supply your graph id and the variant you want to use (for example, `current`). You can always find a a graph's ref at the top of its Schema Reference page in Studio.

> When running your gateway in an environment where outbound traffic to the internet is restricted, consult the [directions for configuring a proxy](https://www.apollographql.com/docs/apollo-server/proxy-configuration/) within Apollo Server.

Expand Down
1 change: 0 additions & 1 deletion docs/source/quickstart-pt-2.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,6 @@ So now, how do we connect and authenticate our gateway with Apollo Studio? With

```shell
APOLLO_KEY=YOUR_API_KEY
APOLLO_SCHEMA_CONFIG_DELIVERY_ENDPOINT=https://uplink.api.apollographql.com/
```

4. Add the `dotenv` Node.js library to your project:
Expand Down
2 changes: 1 addition & 1 deletion federation-integration-testsuite-js/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "apollo-federation-integration-testsuite",
"private": true,
"version": "0.26.0",
"version": "0.27.0",
"description": "Apollo Federation Integrations / Test Fixtures",
"main": "dist/index.js",
"types": "dist/index.d.ts",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ export const url = `https://${name}.api.com`;
export const typeDefs = gql`
directive @stream on FIELD
directive @transform(from: String!) on FIELD
directive @tag(name: String!) repeatable on FIELD_DEFINITION

schema {
query: RootQuery
Expand Down
40 changes: 19 additions & 21 deletions federation-integration-testsuite-js/src/fixtures/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,26 +8,9 @@ import * as reviewsWithUpdate from './special-cases/reviewsWithUpdate';
import * as accountsWithoutTag from './special-cases/accountsWithoutTag';
import * as reviewsWithoutTag from './special-cases/reviewsWithoutTag';

export {
accounts,
books,
documents,
inventory,
product,
reviews,
reviewsWithUpdate,
};
const fixtures = [accounts, books, documents, inventory, product, reviews];

export const fixtures = [
accounts,
books,
documents,
inventory,
product,
reviews,
];

export const fixturesWithUpdate = [
const fixturesWithUpdate = [
accounts,
books,
documents,
Expand All @@ -36,7 +19,7 @@ export const fixturesWithUpdate = [
reviewsWithUpdate,
];

export const fixturesWithoutTag = [
const fixturesWithoutTag = [
accountsWithoutTag,
books,
documents,
Expand All @@ -45,11 +28,26 @@ export const fixturesWithoutTag = [
reviewsWithoutTag,
];

export const fixtureNames = [
const fixtureNames = [
accounts.name,
product.name,
inventory.name,
reviews.name,
books.name,
documents.name,
];

export { superGraphWithInaccessible } from './special-cases/supergraphWithInaccessible';
export {
accounts,
books,
documents,
inventory,
product,
reviews,
reviewsWithUpdate,
fixtures,
fixturesWithUpdate,
fixturesWithoutTag,
fixtureNames,
};
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ export const url = `https://${name}.api.com`;
export const typeDefs = gql`
directive @stream on FIELD
directive @transform(from: String!) on FIELD
directive @tag(name: String!) repeatable on FIELD_DEFINITION

extend type Query {
topReviews(first: Int = 5): [Review]
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import { composeAndValidate } from '@apollo/federation';
import { assertCompositionSuccess } from '@apollo/federation/dist/composition/utils';
import {
DirectiveDefinitionNode,
SchemaDefinitionNode,
DocumentNode,
DirectiveNode,
parse,
visit,
} from 'graphql';
import { fixtures } from '..';

const compositionResult = composeAndValidate(fixtures);
assertCompositionSuccess(compositionResult);
const parsed = parse(compositionResult.supergraphSdl);

// We need to collect the AST for the inaccessible definition as well
// as the @core and @inaccessible usages. Parsing SDL is a fairly
// clean approach to this and easier to update than handwriting the AST.
const [inaccessibleDefinition, schemaDefinition] = parse(`#graphql
# inaccessibleDefinition
directive @inaccessible on FIELD_DEFINITION | OBJECT | INTERFACE | UNION
schema
# inaccessibleCoreUsage
@core(feature: "https://specs.apollo.dev/inaccessible/v0.1")
# inaccessibleUsage
@inaccessible {
query: Query
}
`).definitions as [DirectiveDefinitionNode, SchemaDefinitionNode];

const [inaccessibleCoreUsage, inaccessibleUsage] =
schemaDefinition.directives as [DirectiveNode, DirectiveNode];

// Append the AST with the inaccessible definition, and @core inaccessible usage
let superGraphWithInaccessible: DocumentNode = visit(parsed, {
Document(node) {
return {
...node,
definitions: [...node.definitions, inaccessibleDefinition],
};
},
SchemaDefinition(node) {
return {
...node,
directives: [...(node.directives ?? []), inaccessibleCoreUsage],
};
},
});

// Append @inaccessible usage to the `Car` type, `ssn` field, and `topCars` field
superGraphWithInaccessible = visit(
superGraphWithInaccessible,
{
ObjectTypeDefinition(node) {
if (node.name.value === 'Car') {
return {
...node,
directives: [...(node.directives ?? []), inaccessibleUsage],
};
}
return node;
},
FieldDefinition(node) {
if (node.name.value === 'ssn') {
return {
...node,
directives: [...(node.directives ?? []), inaccessibleUsage],
};
}
if (node.name.value === 'topCars') {
return {
...node,
directives: [...(node.directives ?? []), inaccessibleUsage],
};
}
return node;
}
},
);

export { superGraphWithInaccessible };
5 changes: 5 additions & 0 deletions federation-js/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,13 @@

> 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. 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.

- Narrow `graphql` peer dependency to a more fitting range `^15.4.0` based on our current usage of the package. This requirement was introduced by, but not captured in, changes within the recently released `@apollo/[email protected]`. As such, this change will be released as a `patch` since the breaking change already accidentally happened and this is a correction to that oversight. [PR #913](https://github.com/apollographql/federation/pull/913)

## v0.27.0

- Skip missing types while iterating over field directive usages. It's possible to capture directive usages on fields whose types don't actually exist in the schema (due to invalid composition). See PR for more details. [PR #868](https://github.com/apollographql/federation/pull/868)
- Disregard @inaccessible directive in subgraphs. This is a bit of a retrace on a previous decision. @inaccessible will now be achieved strictly through a combination of @tag and Studio usage. [PR #880](https://github.com/apollographql/federation/pull/880)
- Require a @tag directive definition in subgraphs when there are @tag usages. [PR #882](https://github.com/apollographql/federation/pull/882)

## v0.26.0

Expand Down
4 changes: 2 additions & 2 deletions federation-js/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@apollo/federation",
"version": "0.26.0",
"version": "0.27.1",
"description": "Apollo Federation Utilities",
"main": "dist/index.js",
"types": "dist/index.d.ts",
Expand All @@ -27,6 +27,6 @@
"lodash.xorby": "^4.7.0"
},
"peerDependencies": {
"graphql": "^14.5.0 || ^15.0.0"
"graphql": "^15.4.0"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,7 @@ describe('unknown types', () => {
const inventory = {
name: 'inventory',
typeDefs: gql`
directive @tag(name: String!) repeatable on FIELD_DEFINITION
extend type Product @key(fields: "id") {
id: ID! @external @tag(name: "hi from inventory")
}
Expand All @@ -189,7 +190,7 @@ describe('unknown types', () => {
"locations": Array [
Object {
"column": 1,
"line": 2,
"line": 3,
},
],
"message": "[inventory] Product -> \`Product\` is an extension type, but \`Product\` is not defined in any service",
Expand Down
8 changes: 8 additions & 0 deletions federation-js/src/composition/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,14 @@ export function stripExternalFieldsFromTypeDefs(
return { typeDefsWithoutExternalFields, strippedFields };
}

export function stripDescriptions(astNode: ASTNode) {
return visit(astNode, {
enter(node) {
return 'description' in node ? { ...node, description: undefined } : node;
},
});
}

export function stripTypeSystemDirectivesFromTypeDefs(typeDefs: DocumentNode) {
const typeDefsWithoutTypeSystemDirectives = visit(typeDefs, {
Directive(node) {
Expand Down
Loading