AWS AppSync 构造库
本单元中更高层次的构件的API是实验性的并正在积极开发中. 在今后任何版本中,它们都须作非背向相容的修改或去除。 这些是 不适用 语义版本 模型和断开的更改 在发行笔记中宣布. 这意味着虽然你可能使用它们,但可能需要更新 当更新到此软件包的更新版本时,您的源代码.
这个 @aws-cdk/aws-appsync 软件包中包含用于灵活建筑的构造
使用 GraphQL 的 API .
import * as appsync from '@aws-cdk/aws-appsync-alpha';
示例
迪纳摩DB
图QL API 示例 AWS_IAM 授权 进入迪纳摩Db
后端数据源.
GraphQL 计划文件 schema.graphql数字 :
type demo {
id: String!
version: String!
}
type Query {
getDemos: [ demo! ]
}
input DemoInput {
version: String!
}
type Mutation {
addDemo(input: DemoInput!): demo
}
CDK 堆栈文件 app-stack.ts数字 :
const api = new appsync.GraphqlApi(this, 'Api', {
name: 'demo',
schema: appsync.SchemaFile.fromAsset(path.join(__dirname, 'schema.graphql')),
authorizationConfig: {
defaultAuthorization: {
authorizationType: appsync.AuthorizationType.IAM,
},
},
xrayEnabled: true,
});
const demoTable = new dynamodb.Table(this, 'DemoTable', {
partitionKey: {
name: 'id',
type: dynamodb.AttributeType.STRING,
},
});
const demoDS = api.addDynamoDbDataSource('demoDataSource', demoTable);
// Resolver for the Query "getDemos" that scans the DynamoDb table and returns the entire list.
// Resolver Mapping Template Reference:
// https://docs.aws.amazon.com/appsync/latest/devguide/resolver-mapping-template-reference-dynamodb.html
demoDS.createResolver('QueryGetDemosResolver', {
typeName: 'Query',
fieldName: 'getDemos',
requestMappingTemplate: appsync.MappingTemplate.dynamoDbScanTable(),
responseMappingTemplate: appsync.MappingTemplate.dynamoDbResultList(),
});
// Resolver for the Mutation "addDemo" that puts the item into the DynamoDb table.
demoDS.createResolver('MutationAddDemoResolver', {
typeName: 'Mutation',
fieldName: 'addDemo',
requestMappingTemplate: appsync.MappingTemplate.dynamoDbPutItem(
appsync.PrimaryKey.partition('id').auto(),
appsync.Values.projecting('input'),
),
responseMappingTemplate: appsync.MappingTemplate.dynamoDbResultItem(),
});
//To enable DynamoDB read consistency with the `MappingTemplate`:
demoDS.createResolver('QueryGetDemosConsistentResolver', {
typeName: 'Query',
fieldName: 'getDemosConsistent',
requestMappingTemplate: appsync.MappingTemplate.dynamoDbScanTable(true),
responseMappingTemplate: appsync.MappingTemplate.dynamoDbResultList(),
});
无服务器的Aurora
AppSync 为针对Amazon Aurora执行SQL命令提供数据源 无服务器集群. 您可以使用 AppSync 解析器执行 SQL 语句 与 GraphQL 查询、 突变和订阅的 Data API 对齐.
// Create username and password secret for DB Cluster
const secret = new rds.DatabaseSecret(this, 'AuroraSecret', {
username: 'clusteradmin',
});
// The VPC to place the cluster in
const vpc = new ec2.Vpc(this, 'AuroraVpc');
// Create the serverless cluster, provide all values needed to customise the database.
const cluster = new rds.ServerlessCluster(this, 'AuroraCluster', {
engine: rds.DatabaseClusterEngine.AURORA_MYSQL,
vpc,
credentials: { username: 'clusteradmin' },
clusterIdentifier: 'db-endpoint-test',
defaultDatabaseName: 'demos',
});
// Build a data source for AppSync to access the database.
declare const api: appsync.GraphqlApi;
const rdsDS = api.addRdsDataSource('rds', cluster, secret, 'demos');
// Set up a resolver for an RDS query.
rdsDS.createResolver('QueryGetDemosRdsResolver', {
typeName: 'Query',
fieldName: 'getDemosRds',
requestMappingTemplate: appsync.MappingTemplate.fromString(`
{
"version": "2018-05-29",
"statements": [
"SELECT * FROM demos"
]
}
`),
responseMappingTemplate: appsync.MappingTemplate.fromString(`
$utils.toJson($utils.rds.toJsonObject($ctx.result)[0])
`),
});
// Set up a resolver for an RDS mutation.
rdsDS.createResolver('MutationAddDemoRdsResolver', {
typeName: 'Mutation',
fieldName: 'addDemoRds',
requestMappingTemplate: appsync.MappingTemplate.fromString(`
{
"version": "2018-05-29",
"statements": [
"INSERT INTO demos VALUES (:id, :version)",
"SELECT * WHERE id = :id"
],
"variableMap": {
":id": $util.toJson($util.autoId()),
":version": $util.toJson($ctx.args.version)
}
}
`),
responseMappingTemplate: appsync.MappingTemplate.fromString(`
$utils.toJson($utils.rds.toJsonObject($ctx.result)[1][0])
`),
});
HTTP 终点
GraphQL 计划文件 schema.graphql数字 :
type job {
id: String!
version: String!
}
input DemoInput {
version: String!
}
type Mutation {
callStepFunction(input: DemoInput!): job
}
GraphQL 请求绘图模板 request.vtl数字 :
{
"version": "2018-05-29",
"method": "POST",
"resourcePath": "/",
"params": {
"headers": {
"content-type": "application/x-amz-json-1.0",
"x-amz-target":"AWSStepFunctions.StartExecution"
},
"body": {
"stateMachineArn": "<your step functions arn>",
"input": "{ \"id\": \"$context.arguments.id\" }"
}
}
}
图QL 响应映射模板 response.vtl数字 :
{
"id": "${context.result.id}"
}
CDK 堆栈文件 app-stack.ts数字 :
const api = new appsync.GraphqlApi(this, 'api', {
name: 'api',
schema: appsync.SchemaFile.fromAsset(path.join(__dirname, 'schema.graphql')),
});
const httpDs = api.addHttpDataSource(
'ds',
'https://states.amazonaws.com',
{
name: 'httpDsWithStepF',
description: 'from appsync to StepFunctions Workflow',
authorizationConfig: {
signingRegion: 'us-east-1',
signingServiceName: 'states',
}
}
);
httpDs.createResolver('MutationCallStepFunctionResolver', {
typeName: 'Mutation',
fieldName: 'callStepFunction',
requestMappingTemplate: appsync.MappingTemplate.fromFile('request.vtl'),
responseMappingTemplate: appsync.MappingTemplate.fromFile('response.vtl'),
});
亚马逊 OpenSearch 服务
AppSync 已建立支持 Amazon OpenSearch Service( 继承到 Amazon) Elasticsearch Service),来自通过您的 AWS 账户提供的域. 你们可以 使用 AppSync 解析器执行 GraphQL 操作,例如查询、突变和 订阅.
import * as opensearch from 'aws-cdk-lib/aws-opensearchservice';
const user = new iam.User(this, 'User');
const domain = new opensearch.Domain(this, 'Domain', {
version: opensearch.EngineVersion.OPENSEARCH_1_3,
removalPolicy: RemovalPolicy.DESTROY,
fineGrainedAccessControl: { masterUserArn: user.userArn },
encryptionAtRest: { enabled: true },
nodeToNodeEncryption: true,
enforceHttps: true,
});
declare const api: appsync.GraphqlApi;
const ds = api.addOpenSearchDataSource('ds', domain);
ds.createResolver('QueryGetTestsResolver', {
typeName: 'Query',
fieldName: 'getTests',
requestMappingTemplate: appsync.MappingTemplate.fromString(JSON.stringify({
version: '2017-02-28',
operation: 'GET',
path: '/id/post/_search',
params: {
headers: {},
queryString: {},
body: { from: 0, size: 50 },
},
})),
responseMappingTemplate: appsync.MappingTemplate.fromString(`[
#foreach($entry in $context.result.hits.hits)
#if( $velocityCount > 1 ) , #end
$utils.toJson($entry.get("_source"))
#end
]`),
});
自定义域名
对于很多用途,您可能想要将自定义域名与您的域名关联 图QL API. 这可以在API创建期间完成.
import * as acm from 'aws-cdk-lib/aws-certificatemanager';
import * as route53 from 'aws-cdk-lib/aws-route53';
const myDomainName = 'api.example.com';
const certificate = new acm.Certificate(this, 'cert', { domainName: myDomainName });
const schema = new appsync.SchemaFile({ filePath: 'mySchemaFile' })
const api = new appsync.GraphqlApi(this, 'api', {
name: 'myApi',
schema,
domainName: {
certificate,
domainName: myDomainName,
},
});
// hosted zone and route53 features
declare const hostedZoneId: string;
declare const zoneName = 'example.com';
// hosted zone for adding appsync domain
const zone = route53.HostedZone.fromHostedZoneAttributes(this, `HostedZone`, {
hostedZoneId,
zoneName,
});
// create a cname to the appsync domain. will map to something like xxxx.cloudfront.net
new route53.CnameRecord(this, `CnameApiRecord`, {
recordName: 'api',
zone,
domainName: api.appSyncDomainName,
});
日志组
AppSync 自动创建带有名称的日志组 /aws/appsync/apis/<graphql_api_id> 与
日志数据集永不过期 。 如果您想要设定不同的过期期, 请使用 logConfig.retention 属性.
要获取 GraphQL API 的日志组 logs.ILogGroup 使用该 logGroup 财产的财产
GraphqlApi 构造.
import * as logs from 'aws-cdk-lib/aws-logs';
const logConfig: appsync.LogConfig = {
retention: logs.RetentionDays.ONE_WEEK,
};
new appsync.GraphqlApi(this, 'api', {
authorizationConfig: {},
name: 'myApi',
schema: appsync.SchemaFile.fromAsset(path.join(__dirname, 'myApi.graphql')),
logConfig,
});
司马
您可以使用本地文件使用 SchemaFile.fromAsset
const api = new appsync.GraphqlApi(this, 'api', {
name: 'myApi',
schema: appsync.SchemaFile.fromAsset(path.join(__dirname, 'schema.graphl')),
});
ISchema 计划
可通过实施 ISchema
接口。 一个例子是 CodeFirstSchema 提供的类别
awscdk-appsync-utils (英语)
进口
任意图形QL 堆栈外已创建的 Api 可以导入自
另一个堆入您的 CDK 应用程序。 利用 fromXxx 函数,您有
通过数据源和解析器 IGraphqlApi 接口.
declare const api: appsync.GraphqlApi;
declare const table: dynamodb.Table;
const importedApi = appsync.GraphqlApi.fromGraphqlApiAttributes(this, 'IApi', {
graphqlApiId: api.apiId,
graphqlApiArn: api.arn,
});
importedApi.addDynamoDbDataSource('TableDataSource', table);
如果你不说明 graphqlArn 内 fromXxxAttributes,CDK 将自动生成
预想数 arn 用于导入的 api,考虑到 apiId。用于创建数据
来源和解决者,a apiId 足够了.
授权
GraphQL API有多种授权类型,以适应不同的 访问使用案例。 它们是:
- API 密钥( R)
AuthorizationType.API_KEY(中文(简体) ) - 亚马逊·科尼托用户池(英语:Amazon Cognto Users pools (
AuthorizationType.USER_POOL(中文(简体) ) - 打开ID 连接( O)
AuthorizationType.OPENID_CONNECT(中文(简体) ) - AWS 身份和访问管理
AuthorizationType.AWS_IAM(中文(简体) ) - AWS 兰布达( Lambda)
AuthorizationType.AWS_LAMBDA(中文(简体) )
这些类型可以在单个API中同时使用,允许不同类型的客户端使用 访问数据。 当指定授权类型时,也可以指定相应的类型 授权模式以完成定义您的授权 。 例如, 这是一个 GraphQL API aWS蓝巴达授权.
import * as lambda from 'aws-cdk-lib/aws-lambda';
declare const authFunction: lambda.Function;
new appsync.GraphqlApi(this, 'api', {
name: 'api',
schema: appsync.SchemaFile.fromAsset(path.join(__dirname, 'appsync.test.graphql')),
authorizationConfig: {
defaultAuthorization: {
authorizationType: appsync.AuthorizationType.LAMBDA,
lambdaAuthorizerConfig: {
handler: authFunction,
// can also specify `resultsCacheTtl` and `validationRegex`.
},
},
},
});
权限
使用时 AWS_IAM 作为IAM角色GraphQL API的授权类型
访问 API 必须使用正确的权限.
配置权限时,您可以指定特定资源仅为
无障碍 IAM 授权。 例如,如果只允许可变性
页:1 IAM 您将配置以下授权访问 .
单位 schema.graphql数字 :
type Mutation {
updateExample(...): ...
@aws_iam
}
单位 IAM数字 :
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"appsync:GraphQL"
],
"Resource": [
"arn:aws:appsync:REGION:ACCOUNT_ID:apis/GRAPHQL_ID/types/Mutation/fields/updateExample"
]
}
]
}
见 文档 更多细节.
为方便起见,CDK提供 grant API (英语).
使用 grant 函数用于更多的颗粒式授权.
const role = new iam.Role(this, 'Role', {
assumedBy: new iam.ServicePrincipal('lambda.amazonaws.com'),
});
declare const api: appsync.GraphqlApi;
api.grant(role, appsync.IamResource.custom('types/Mutation/fields/updateExample'), 'appsync:GraphQL');
资源
为了使用 grant 函数,需要使用类 IamResource。 。 。 .
-
IamResource.custom(...arns)允许自定义 ARN 并需要一个参数. -
IamResouce.ofType(type, ...fields)允许ARN用于类型及其字段. -
IamResource.all()允许所有资源.
通用权限
或者,您可以使用更通用的 grant 用于实现相同用途的函数.
其中包括:
- 混合(用于允许进入突变场)
- 授权查询( 用于授权访问查询字段)
- 赠款订阅(用于授权访问订阅栏)
declare const api: appsync.GraphqlApi;
declare const role: iam.Role;
// For generic types
api.grantMutation(role, 'updateExample');
// For custom types and granular design
api.grant(role, appsync.IamResource.ofType('Mutation', 'updateExample'), 'appsync:GraphQL');
管道解析器和 AppSync 函数
AppSync 函数是本地函数,可以执行某些操作到 a 后端数据源. 开发者可以组成操作(功能)并执行 以管道解析器排列.
declare const api: appsync.GraphqlApi;
const appsyncFunction = new appsync.AppsyncFunction(this, 'function', {
name: 'appsync_function',
api,
dataSource: api.addNoneDataSource('none'),
requestMappingTemplate: appsync.MappingTemplate.fromFile('request.vtl'),
responseMappingTemplate: appsync.MappingTemplate.fromFile('response.vtl'),
});
AppSync 函数与管道解析器同步使用,以组成多个函数 操作.
declare const api: appsync.GraphqlApi;
declare const appsyncFunction: appsync.AppsyncFunction;
const pipelineResolver = new appsync.Resolver(this, 'pipeline', {
api,
dataSource: api.addNoneDataSource('none'),
typeName: 'typeName',
fieldName: 'fieldName',
requestMappingTemplate: appsync.MappingTemplate.fromFile('beforeRequest.vtl'),
pipelineConfig: [appsyncFunction],
responseMappingTemplate: appsync.MappingTemplate.fromFile('afterResponse.vtl'),
});
更多了解管道解析器和 AppSync 函数 这里。 。 。 .