Skip to content

Commit

Permalink
Merge pull request #892 from apollographql/release-gateway-0.34
Browse files Browse the repository at this point in the history
Release
* @apollo/[email protected]
* @apollo/[email protected]
* @apollo/[email protected]
* @apollo/[email protected]

PRs:
* feat(gateway): Default to Uplink for composed supergraph managed federation (#881)
* fix(federation): Require user-defined @tag directive definition (#882)
* Remove @inaccessible elements when converting to API schema (#807)
* Move toAPISchema call into try/catch block (#894)
* fix(gateway): Prevent inaccessible type names from being leaked in error messages (#893)
* docs: rm instruction to set APOLLO_SCHEMA_CONFIG_DELIVERY_ENDPOINT for Uplink (#899)
* fix(gateway): Remove path, query and variables field from subgraph error responses (#900)
  • Loading branch information
trevor-scheer authored Jul 21, 2021
2 parents 47d5c42 + bc7f1a5 commit 6d48698
Show file tree
Hide file tree
Showing 44 changed files with 1,408 additions and 215 deletions.
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
7 changes: 2 additions & 5 deletions docs/source/managed-federation/setup.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -53,17 +53,14 @@ Like your subgraphs, your gateway uses an API key to identify itself to Studio.

<ObtainGraphApiKey />

After obtaining your graph API key, you set three environment variables in your gateway's environment. If you're using a `.env` file with a library like [`dotenv`](https://www.npmjs.com/package/dotenv), those environment variables look like this:
After obtaining your graph API key, you set two environment variables in your gateway's environment. If you're using a `.env` file with a library like [`dotenv`](https://www.npmjs.com/package/dotenv), those environment variables look like this:

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

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.
You can also set this value directly in the command you use to start your gateway.

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.

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.
- _Nothing yet! Stay tuned!_

## 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
2 changes: 1 addition & 1 deletion 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.0",
"description": "Apollo Federation Utilities",
"main": "dist/index.js",
"types": "dist/index.d.ts",
Expand Down
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

0 comments on commit 6d48698

Please sign in to comment.