Skip to content

Commit

Permalink
Merge branch 'master' into cr-flatten-buffer
Browse files Browse the repository at this point in the history
  • Loading branch information
mergify[bot] authored Aug 28, 2020
2 parents 7bbd5c8 + c5bb55c commit 5e54caa
Show file tree
Hide file tree
Showing 84 changed files with 2,430 additions and 1,495 deletions.
8 changes: 4 additions & 4 deletions .mergify.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ pull_request_rules:
- "#changes-requested-reviews-by=0"
- status-success~=AWS CodeBuild us-east-1
#- status-success=Semantic Pull Request
- status-success=mandatory-changes
- status-success=validate-pr
- name: automatic merge (2+ approvers)
actions:
comment:
Expand All @@ -56,7 +56,7 @@ pull_request_rules:
- "#changes-requested-reviews-by=0"
- status-success~=AWS CodeBuild us-east-1
#- status-success=Semantic Pull Request
- status-success=mandatory-changes
- status-success=validate-pr
- name: automatic merge (no-squash)
actions:
comment:
Expand All @@ -82,7 +82,7 @@ pull_request_rules:
- "#changes-requested-reviews-by=0"
- status-success~=AWS CodeBuild us-east-1
#- status-success=Semantic Pull Request
- status-success=mandatory-changes
- status-success=validate-pr
- name: remove stale reviews
actions:
dismiss_reviews:
Expand Down Expand Up @@ -126,4 +126,4 @@ pull_request_rules:
- "#changes-requested-reviews-by=0"
- status-success~=AWS CodeBuild us-east-1
#- status-success=Semantic Pull Request
- status-success=mandatory-changes
- status-success=validate-pr
169 changes: 100 additions & 69 deletions CHANGELOG.md

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion lerna.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,5 @@
"tools/*"
],
"rejectCycles": "true",
"version": "1.60.0"
"version": "1.61.0"
}
73 changes: 57 additions & 16 deletions packages/@aws-cdk/aws-appsync/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,7 @@ import * as db from '@aws-cdk/aws-dynamodb';

const api = new appsync.GraphQLApi(stack, 'Api', {
name: 'demo',
schemaDefinition: appsync.SchemaDefinition.FILE,
schemaDefinitionFile: join(__dirname, 'schema.graphql'),
schema: appsync.Schema.fromAsset(join(__dirname, 'schema.graphql')),
authorizationConfig: {
defaultAuthorization: {
authorizationType: appsync.AuthorizationType.IAM
Expand Down Expand Up @@ -83,7 +82,53 @@ demoDS.createResolver({
});
```

## Imports
### Schema

Every GraphQL Api needs a schema to define the Api. CDK offers `appsync.Schema`
for static convenience methods for various types of schema declaration: code-first
or schema-first.

#### Code-First

When declaring your GraphQL Api, CDK defaults to a code-first approach if the
`schema` property is not configured.

```ts
const api = new appsync.GraphQLApi(stack, 'api', { name: 'myApi' });
```

CDK will declare a `Schema` class that will give your Api access functions to
define your schema code-first: `addType`, `addObjectType`, `addToSchema`, etc.

You can also declare your `Schema` class outside of your CDK stack, to define
your schema externally.

```ts
const schema = new appsync.Schema();
schema.addObjectType('demo', {
definition: { id: appsync.GraphqlType.id() },
});
const api = new appsync.GraphQLApi(stack, 'api', {
name: 'myApi',
schema
});
```

See the [code-first schema](#Code-First-Schema) section for more details.

#### Schema-First

You can define your GraphQL Schema from a file on disk. For convenience, use
the `appsync.Schema.fromAsset` to specify the file representing your schema.

```ts
const api = appsync.GraphQLApi(stack, 'api', {
name: 'myApi',
schema: appsync.Schema.fromAsset(join(__dirname, 'schema.graphl')),
});
```

### Imports

Any GraphQL Api that has been created outside the stack can be imported from
another stack into your CDK app. Utilizing the `fromXxx` function, you have
Expand All @@ -101,7 +146,7 @@ If you don't specify `graphqlArn` in `fromXxxAttributes`, CDK will autogenerate
the expected `arn` for the imported api, given the `apiId`. For creating data
sources and resolvers, an `apiId` is sufficient.

## Permissions
### Permissions

When using `AWS_IAM` as the authorization type for GraphQL API, an IAM Role
with correct permissions must be used for access to API.
Expand Down Expand Up @@ -153,7 +198,7 @@ const api = new appsync.GraphQLApi(stack, 'API', {
api.grant(role, appsync.IamResource.custom('types/Mutation/fields/updateExample'), 'appsync:GraphQL')
```

### IamResource
#### IamResource

In order to use the `grant` functions, you need to use the class `IamResource`.

Expand All @@ -163,7 +208,7 @@ In order to use the `grant` functions, you need to use the class `IamResource`.

- `IamResource.all()` permits ALL resources.

### Generic Permissions
#### Generic Permissions

Alternatively, you can use more generic `grant` functions to accomplish the same usage.

Expand Down Expand Up @@ -280,7 +325,6 @@ import * as schema from './object-types';

const api = new appsync.GraphQLApi(stack, 'Api', {
name: 'demo',
schemaDefinition: appsync.SchemaDefinition.CODE,
});

this.objectTypes = [ schema.Node, schema.Film ];
Expand All @@ -294,13 +338,12 @@ api.addType('Query', {
args: schema.args,
requestMappingTemplate: dummyRequest,
responseMappingTemplate: dummyResponse,
},
}),
}
});
})
});

this.objectTypes.map((t) => api.appendToSchema(t));
Object.keys(filmConnections).forEach((key) => api.appendToSchema(filmConnections[key]));
this.objectTypes.map((t) => api.addType(t));
Object.keys(filmConnections).forEach((key) => api.addType(filmConnections[key]));
```

Notice how we can utilize the `generateEdgeAndConnection` function to generate
Expand Down Expand Up @@ -457,7 +500,6 @@ You can create Object Types in three ways:
```ts
const api = new appsync.GraphQLApi(stack, 'Api', {
name: 'demo',
schemaDefinition: appsync.SchemaDefinition.CODE,
});
const demo = new appsync.ObjectType('Demo', {
defintion: {
Expand All @@ -466,7 +508,7 @@ You can create Object Types in three ways:
},
});

api.appendToSchema(object.toString());
api.addType(object);
```
> This method allows for reusability and modularity, ideal for larger projects.
For example, imagine moving all Object Type definition outside the stack.
Expand All @@ -490,7 +532,7 @@ You can create Object Types in three ways:
`cdk-stack.ts` - a file containing our cdk stack
```ts
import { demo } from './object-types';
api.appendToSchema(demo.toString());
api.addType(demo);
```

2. Object Types can be created ***externally*** from an Interface Type.
Expand All @@ -513,7 +555,6 @@ You can create Object Types in three ways:
```ts
const api = new appsync.GraphQLApi(stack, 'Api', {
name: 'demo',
schemaDefinition: appsync.SchemaDefinition.CODE,
});
api.addType('Demo', {
defintion: {
Expand Down
100 changes: 22 additions & 78 deletions packages/@aws-cdk/aws-appsync/lib/graphqlapi.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { readFileSync } from 'fs';
import { IUserPool } from '@aws-cdk/aws-cognito';
import { ManagedPolicy, Role, ServicePrincipal, Grant, IGrantable } from '@aws-cdk/aws-iam';
import { CfnResource, Construct, Duration, IResolvable, Stack } from '@aws-cdk/core';
import { CfnApiKey, CfnGraphQLApi, CfnGraphQLSchema } from './appsync.generated';
import { IGraphqlApi, GraphqlApiBase } from './graphqlapi-base';
import { ObjectType, ObjectTypeProps } from './schema-intermediate';
import { Schema } from './schema';
import { IIntermediateType } from './schema-base';

/**
* enum with all possible values for AppSync authorization type
Expand Down Expand Up @@ -201,21 +201,6 @@ export interface LogConfig {
readonly fieldLogLevel?: FieldLogLevel;
}

/**
* Enum containing the different modes of schema definition
*/
export enum SchemaDefinition {
/**
* Define schema through functions like addType, addQuery, etc.
*/
CODE = 'CODE',

/**
* Define schema in a file, i.e. schema.graphql
*/
FILE = 'FILE',
}

/**
* Properties for an AppSync GraphQL API
*/
Expand All @@ -242,18 +227,13 @@ export interface GraphQLApiProps {
/**
* GraphQL schema definition. Specify how you want to define your schema.
*
* SchemaDefinition.CODE allows schema definition through CDK
* SchemaDefinition.FILE allows schema definition through schema.graphql file
* Schema.fromFile(filePath: string) allows schema definition through schema.graphql file
*
* @experimental
*/
readonly schemaDefinition: SchemaDefinition;
/**
* File containing the GraphQL schema definition. You have to specify a definition or a file containing one.
* @default - schema will be generated code-first (i.e. addType, addObjectType, etc.)
*
* @default - Use schemaDefinition
* @experimental
*/
readonly schemaDefinitionFile?: string;
readonly schema?: Schema;
/**
* A flag indicating whether or not X-Ray tracing is enabled for the GraphQL API.
*
Expand Down Expand Up @@ -390,9 +370,9 @@ export class GraphQLApi extends GraphqlApiBase {
public readonly name: string;

/**
* underlying CFN schema resource
* the schema attached to this api
*/
public readonly schema: CfnGraphQLSchema;
public readonly schema: Schema;

/**
* the configured API key, if present
Expand All @@ -401,9 +381,9 @@ export class GraphQLApi extends GraphqlApiBase {
*/
public readonly apiKey?: string;

private schemaMode: SchemaDefinition;
private schemaResource: CfnGraphQLSchema;
private api: CfnGraphQLApi;
private _apiKey?: CfnApiKey;
private apiKeyResource?: CfnApiKey;

constructor(scope: Construct, id: string, props: GraphQLApiProps) {
super(scope, id);
Expand All @@ -429,16 +409,16 @@ export class GraphQLApi extends GraphqlApiBase {
this.arn = this.api.attrArn;
this.graphQlUrl = this.api.attrGraphQlUrl;
this.name = this.api.name;
this.schemaMode = props.schemaDefinition;
this.schema = this.defineSchema(props.schemaDefinitionFile);
this.schema = props.schema ?? new Schema();
this.schemaResource = this.schema.bind(this);

if (modes.some((mode) => mode.authorizationType === AuthorizationType.API_KEY)) {
const config = modes.find((mode: AuthorizationMode) => {
return mode.authorizationType === AuthorizationType.API_KEY && mode.apiKeyConfig;
})?.apiKeyConfig;
this._apiKey = this.createAPIKey(config);
this._apiKey.addDependsOn(this.schema);
this.apiKey = this._apiKey.attrApiKey;
this.apiKeyResource = this.createAPIKey(config);
this.apiKeyResource.addDependsOn(this.schemaResource);
this.apiKey = this.apiKeyResource.attrApiKey;
}
}

Expand Down Expand Up @@ -515,7 +495,7 @@ export class GraphQLApi extends GraphqlApiBase {
* @param construct the dependee
*/
public addSchemaDependency(construct: CfnResource): boolean {
construct.addDependsOn(this.schema);
construct.addDependsOn(this.schemaResource);
return true;
}

Expand Down Expand Up @@ -584,29 +564,6 @@ export class GraphQLApi extends GraphqlApiBase {
});
}

/**
* Define schema based on props configuration
* @param file the file name/s3 location of Schema
*/
private defineSchema(file?: string): CfnGraphQLSchema {
let definition;

if ( this.schemaMode === SchemaDefinition.FILE && !file) {
throw new Error('schemaDefinitionFile must be configured if using FILE definition mode.');
} else if ( this.schemaMode === SchemaDefinition.FILE && file ) {
definition = readFileSync(file).toString('utf-8');
} else if ( this.schemaMode === SchemaDefinition.CODE && !file ) {
definition = '';
} else if ( this.schemaMode === SchemaDefinition.CODE && file) {
throw new Error('definition mode CODE is incompatible with file definition. Change mode to FILE/S3 or unconfigure schemaDefinitionFile');
}

return new CfnGraphQLSchema(this, 'Schema', {
apiId: this.apiId,
definition,
});
}

/**
* Escape hatch to append to Schema as desired. Will always result
* in a newline.
Expand All @@ -617,31 +574,18 @@ export class GraphQLApi extends GraphqlApiBase {
*
* @experimental
*/
public appendToSchema(addition: string, delimiter?: string): void {
if ( this.schemaMode !== SchemaDefinition.CODE ) {
throw new Error('API cannot append to schema because schema definition mode is not configured as CODE.');
}
const sep = delimiter ?? '';
this.schema.definition = `${this.schema.definition}${sep}${addition}\n`;
public addToSchema(addition: string, delimiter?: string): void {
this.schema.addToSchema(addition, delimiter);
}

/**
* Add an object type to the schema
* Add type to the schema
*
* @param name the name of the object type
* @param props the definition
* @param type the intermediate type to add to the schema
*
* @experimental
*/
public addType(name: string, props: ObjectTypeProps): ObjectType {
if ( this.schemaMode !== SchemaDefinition.CODE ) {
throw new Error('API cannot add type because schema definition mode is not configured as CODE.');
};
const type = new ObjectType(name, {
definition: props.definition,
directives: props.directives,
});
this.appendToSchema(type.toString());
return type;
public addType(type: IIntermediateType): IIntermediateType {
return this.schema.addType(type);
}
}
1 change: 1 addition & 0 deletions packages/@aws-cdk/aws-appsync/lib/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ export * from './key';
export * from './data-source';
export * from './mapping-template';
export * from './resolver';
export * from './schema';
export * from './schema-intermediate';
export * from './schema-field';
export * from './schema-base';
Expand Down
Loading

0 comments on commit 5e54caa

Please sign in to comment.