aws(學習筆記第四十八課) appsync-graphql-dynamodb
- 使用
graphql
來方便操作dynamodb
- 理解
graphql
中的graphql api
,schema
,resolver
學習內容:
graphql
graphql api
schema
resolver
1. 代碼連接和修改
1.1 代碼鏈接
代碼鏈接(appsync-graphql-dynamodb)
1.2 代碼修改
1.2.1 加上必要的depencies
各個resolver
創建的時候,都是需要data_source
的,所以需要事前將resolver
的depencies
加上data source
。
get_one_resolver.add_depends_on(data_source)get_all_resolver.add_depends_on(data_source)save_resolver.add_depends_on(data_source)delete_resolver.add_depends_on(data_source)
1.2.2 加上必要的outputs
CfnOutput(self, "AppSyncApiUrl",value=items_graphql_api.attr_graph_ql_url,description="AppSync GraphQL API URL")CfnOutput(self, "AppSyncApiKey",value=items_api_key.attr_api_key, # 假設已定義 items_api_key = CfnApiKey(...)description="AppSync API Key")
2. 整體架構
- 定義一個
graphql api
- 為了安全訪問,定義一個
api key
- 定義一個
api schema
- 兩個查詢
api
,all
和get one
- 定義兩個更新
api
,delete
和save
- 兩個查詢
- 定義了一個
dynamo table
,用來存儲數據 - 對
schema
定義了四個resolver
all resovler
get one resolver
save resolver
delete resolver
3. 代碼詳細
3.1 定義api
以及api key
table_name = 'items'items_graphql_api = CfnGraphQLApi(self, 'ItemsApi',name='items-api',authentication_type='API_KEY')items_api_key = CfnApiKey(self, 'ItemsApiKey',api_id=items_graphql_api.attr_api_id)
3.2 定義api
的schema
api_schema = CfnGraphQLSchema(self, 'ItemsSchema',api_id=items_graphql_api.attr_api_id,definition=f"""\type {table_name} {{{table_name}Id: ID!name: String}}type Paginated{table_name} {{items: [{table_name}!]!nextToken: String}}type Query {{all(limit: Int, nextToken: String): Paginated{table_name}!getOne({table_name}Id: ID!): {table_name}}}type Mutation {{save(name: String!): {table_name}delete({table_name}Id: ID!): {table_name}}}type Schema {{query: Querymutation: Mutation}}""")
3.3 定義dynamoDB table
items_table = Table(self, 'ItemsTable',table_name=table_name,partition_key=Attribute(name=f'{table_name}Id',type=AttributeType.STRING),billing_mode=BillingMode.PAY_PER_REQUEST,stream=StreamViewType.NEW_IMAGE,# The default removal policy is RETAIN, which means that cdk# destroy will not attempt to delete the new table, and it will# remain in your account until manually deleted. By setting the# policy to DESTROY, cdk destroy will delete the table (even if it# has data in it)removal_policy=RemovalPolicy.DESTROY # NOT recommended for production code)
3.4 定義dynamoDB
訪問的role
,以及data source
這里data source
,可以看出是將graphql api
和dynamoDB
的table
進行關聯。
items_table_role = Role(self, 'ItemsDynamoDBRole',assumed_by=ServicePrincipal('appsync.amazonaws.com'))items_table_role.add_managed_policy(ManagedPolicy.from_aws_managed_policy_name('AmazonDynamoDBFullAccess'))data_source = CfnDataSource(self, 'ItemsDataSource',api_id=items_graphql_api.attr_api_id,name='ItemsDynamoDataSource',type='AMAZON_DYNAMODB',dynamo_db_config=CfnDataSource.DynamoDBConfigProperty(table_name=items_table.table_name,aws_region=self.region),service_role_arn=items_table_role.role_arn)
3.5 定義四個api resolver
3.5.1 get one resolver
get_one_resolver = CfnResolver(self, 'GetOneQueryResolver',api_id=items_graphql_api.attr_api_id,type_name='Query',field_name='getOne',data_source_name=data_source.name,request_mapping_template=f"""\{{"version": "2017-02-28","operation": "GetItem","key": {{"{table_name}Id": $util.dynamodb.toDynamoDBJson($ctx.args.{table_name}Id)}}}}""",response_mapping_template="$util.toJson($ctx.result)")get_one_resolver.add_depends_on(api_schema)get_one_resolver.add_depends_on(data_source)
3.5.2 all resolver
get_all_resolver = CfnResolver(self, 'GetAllQueryResolver',api_id=items_graphql_api.attr_api_id,type_name='Query',field_name='all',data_source_name=data_source.name,request_mapping_template=f"""\{{"version": "2017-02-28","operation": "Scan","limit": $util.defaultIfNull($ctx.args.limit, 20),"nextToken": $util.toJson($util.defaultIfNullOrEmpty($ctx.args.nextToken, null))}}""",response_mapping_template="$util.toJson($ctx.result)")get_all_resolver.add_depends_on(api_schema)get_all_resolver.add_depends_on(data_source)
3.5.3 save resolver
save_resolver = CfnResolver(self, 'SaveMutationResolver',api_id=items_graphql_api.attr_api_id,type_name='Mutation',field_name='save',data_source_name=data_source.name,request_mapping_template=f"""\{{"version": "2017-02-28","operation": "PutItem","key": {{"{table_name}Id": {{ "S": "$util.autoId()" }}}},"attributeValues": {{"name": $util.dynamodb.toDynamoDBJson($ctx.args.name)}}}}""",response_mapping_template="$util.toJson($ctx.result)")save_resolver.add_depends_on(api_schema)save_resolver.add_depends_on(data_source)
3.5.4 delete resolver
delete_resolver = CfnResolver(self, 'DeleteMutationResolver',api_id=items_graphql_api.attr_api_id,type_name='Mutation',field_name='delete',data_source_name=data_source.name,request_mapping_template=f"""\{{"version": "2017-02-28","operation": "DeleteItem","key": {{"{table_name}Id": $util.dynamodb.toDynamoDBJson($ctx.args.{table_name}Id)}}}}""",response_mapping_template="$util.toJson($ctx.result)")delete_resolver.add_depends_on(api_schema)delete_resolver.add_depends_on(data_source)
3.5.5 增加outputs
為了能夠得到graphql api
的endpoint url
,還有訪問api key
,這里進行outputs
的輸出
CfnOutput(self, "AppSyncApiUrl",value=items_graphql_api.attr_graph_ql_url,description="AppSync GraphQL API URL")CfnOutput(self, "AppSyncApiKey",value=items_api_key.attr_api_key, # 假設已定義 items_api_key = CfnApiKey(...)description="AppSync API Key")
4. 執行stack
4.1 執行stack
python -m venv ./venv
source .venv/Scripts/activate
pip install -r requirements.txt
cdk --require-approval never deploy
4.2 使用postman
進行api
調用,更新和查詢dynamoDB table
4.2.1 生成GraphQL Request
4.2.2 使用save
進行數據做成
在authorization
的tab
上進行api key
的設定。
指定完畢,可以看到生成的數據中,已經生成了itemsID
。