From fa9c02dc6bbd0ef0357b3f88487ea6b1aab9325f Mon Sep 17 00:00:00 2001 From: heitorlessa Date: Tue, 28 Feb 2023 17:40:43 +0100 Subject: [PATCH 1/9] chore: add mutation in schema and resolver sample --- examples/event_handler_graphql/sam/template.yaml | 12 ++++++++++++ .../src/getting_started_schema.graphql | 5 +++++ 2 files changed, 17 insertions(+) diff --git a/examples/event_handler_graphql/sam/template.yaml b/examples/event_handler_graphql/sam/template.yaml index 3e2ab60ab10..4c6ca50adc7 100644 --- a/examples/event_handler_graphql/sam/template.yaml +++ b/examples/event_handler_graphql/sam/template.yaml @@ -80,6 +80,10 @@ Resources: listTodos: [Todo] } + type Mutation { + createTodo(title: String!): Todo + } + type Todo { id: ID! userId: String @@ -115,6 +119,14 @@ Resources: FieldName: "getTodo" DataSourceName: !GetAtt TodosFunctionDataSource.Name + CreateTodoResolver: + Type: "AWS::AppSync::Resolver" + Properties: + ApiId: !GetAtt TodosApi.ApiId + TypeName: "Mutation" + FieldName: "createTodo" + DataSourceName: !GetAtt TodosFunctionDataSource.Name + Outputs: TodosFunction: Description: "Hello World Lambda Function ARN" diff --git a/examples/event_handler_graphql/src/getting_started_schema.graphql b/examples/event_handler_graphql/src/getting_started_schema.graphql index b8ef8f995d0..c0d1f8d4281 100644 --- a/examples/event_handler_graphql/src/getting_started_schema.graphql +++ b/examples/event_handler_graphql/src/getting_started_schema.graphql @@ -3,10 +3,15 @@ schema { } type Query { + # these are fields you can attach resolvers to (field: Query, field: getTodo) getTodo(id: ID!): Todo listTodos: [Todo] } +type Mutation { + createTodo(title: String!): Todo +} + type Todo { id: ID! userId: String From ca2517af6fe73d3fcdb1f2fec409e3d2d969d900 Mon Sep 17 00:00:00 2001 From: heitorlessa Date: Tue, 28 Feb 2023 17:41:05 +0100 Subject: [PATCH 2/9] docs: improved explanation about type and field --- docs/core/event_handler/appsync.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/docs/core/event_handler/appsync.md b/docs/core/event_handler/appsync.md index 2fe5896b273..1d10fe2a4e4 100644 --- a/docs/core/event_handler/appsync.md +++ b/docs/core/event_handler/appsync.md @@ -46,7 +46,10 @@ This is the sample infrastructure we are using for the initial examples with a A You can define your functions to match GraphQL types and fields with the `app.resolver()` decorator. -Here's an example where we have two separate functions to resolve `getTodo` and `listTodos` fields within the `Query` type. For completion, we use Scalar type utilities to generate the right output based on our schema definition. +???+ question "What is a type and field?" + A type would be a top-level **GraphQL Type** like `Query`, `Mutation`, `Todo`. A **GraphQL Field** would be `listTodos` under `Query`, or `createTodo` under `Mutation`, or `title` under `Todo`. + +Here's an example with two separate functions to resolve `getTodo` and `listTodos` fields within the `Query` type. For completion, we use [Scalar type utilities](#scalar-functions) to generate the right output based on our schema definition. ???+ important GraphQL arguments are passed as function keyword arguments. From c1382fab13fe0b61df8334bc91d7517f3b598706 Mon Sep 17 00:00:00 2001 From: heitorlessa Date: Tue, 28 Feb 2023 18:03:38 +0100 Subject: [PATCH 3/9] docs: extend resolver with mutation example --- docs/core/event_handler/appsync.md | 8 ++++---- .../src/getting_started_graphql_api_resolver.py | 11 +++++++++++ 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/docs/core/event_handler/appsync.md b/docs/core/event_handler/appsync.md index 1d10fe2a4e4..dd2f51ad3c4 100644 --- a/docs/core/event_handler/appsync.md +++ b/docs/core/event_handler/appsync.md @@ -61,25 +61,25 @@ Here's an example with two separate functions to resolve `getTodo` and `listTodo === "getting_started_graphql_api_resolver.py" - ```python hl_lines="14 20 30 32-33 42 44 55" + ```python hl_lines="14 21 31 33-34 43 45 53 55 70" --8<-- "examples/event_handler_graphql/src/getting_started_graphql_api_resolver.py" ``` === "getting_started_schema.graphql" - ```typescript hl_lines="6-7" + ```typescript hl_lines="6-8 12" --8<-- "examples/event_handler_graphql/src/getting_started_schema.graphql" ``` === "getting_started_get_todo.json" - ```json hl_lines="2-3" + ```json hl_lines="2-3 42" --8<-- "examples/event_handler_graphql/src/getting_started_get_todo.json" ``` === "getting_started_list_todos.json" - ```json hl_lines="2 40 42" + ```json hl_lines="2 40" --8<-- "examples/event_handler_graphql/src/getting_started_list_todos.json" ``` diff --git a/examples/event_handler_graphql/src/getting_started_graphql_api_resolver.py b/examples/event_handler_graphql/src/getting_started_graphql_api_resolver.py index e4879d609f2..670d05e759f 100644 --- a/examples/event_handler_graphql/src/getting_started_graphql_api_resolver.py +++ b/examples/event_handler_graphql/src/getting_started_graphql_api_resolver.py @@ -13,6 +13,7 @@ from aws_lambda_powertools import Logger, Tracer from aws_lambda_powertools.event_handler import AppSyncResolver from aws_lambda_powertools.logging import correlation_paths +from aws_lambda_powertools.utilities.data_classes.appsync import scalar_types_utils from aws_lambda_powertools.utilities.typing import LambdaContext tracer = Tracer() @@ -49,6 +50,16 @@ def list_todos() -> List[Todo]: return todos.json()[:10] +@app.resolver(type_name="Mutation", field_name="createTodo") +@tracer.capture_method +def create_todo(title: str) -> Todo: + payload = ({"userId": scalar_types_utils.make_id(), "title": title, "completed": False},) # dummy UUID str + todo: Response = requests.post("https://jsonplaceholder.typicode.com/todos", json=payload) + todo.raise_for_status() + + return todo.json()["0"] + + @logger.inject_lambda_context(correlation_id_path=correlation_paths.APPSYNC_RESOLVER) @tracer.capture_lambda_handler def lambda_handler(event: dict, context: LambdaContext) -> dict: From f520f37625d1785c0d12a54bde20141caa5041e5 Mon Sep 17 00:00:00 2001 From: heitorlessa Date: Wed, 1 Mar 2023 07:15:26 +0100 Subject: [PATCH 4/9] docs: remove reference to Tile/Todo --- docs/core/event_handler/appsync.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/core/event_handler/appsync.md b/docs/core/event_handler/appsync.md index dd2f51ad3c4..7efc5e11eed 100644 --- a/docs/core/event_handler/appsync.md +++ b/docs/core/event_handler/appsync.md @@ -47,7 +47,7 @@ This is the sample infrastructure we are using for the initial examples with a A You can define your functions to match GraphQL types and fields with the `app.resolver()` decorator. ???+ question "What is a type and field?" - A type would be a top-level **GraphQL Type** like `Query`, `Mutation`, `Todo`. A **GraphQL Field** would be `listTodos` under `Query`, or `createTodo` under `Mutation`, or `title` under `Todo`. + A type would be a top-level **GraphQL Type** like `Query`, `Mutation`, `Todo`. A **GraphQL Field** would be `listTodos` under `Query`, `createTodo` under `Mutation`, etc. Here's an example with two separate functions to resolve `getTodo` and `listTodos` fields within the `Query` type. For completion, we use [Scalar type utilities](#scalar-functions) to generate the right output based on our schema definition. From b549540d621dfb12821dfe861cbf4c9f3e383bf2 Mon Sep 17 00:00:00 2001 From: heitorlessa Date: Wed, 1 Mar 2023 07:15:46 +0100 Subject: [PATCH 5/9] docs: remove tuple reference in payload sample --- .../src/getting_started_graphql_api_resolver.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/event_handler_graphql/src/getting_started_graphql_api_resolver.py b/examples/event_handler_graphql/src/getting_started_graphql_api_resolver.py index 670d05e759f..864734b8782 100644 --- a/examples/event_handler_graphql/src/getting_started_graphql_api_resolver.py +++ b/examples/event_handler_graphql/src/getting_started_graphql_api_resolver.py @@ -53,7 +53,7 @@ def list_todos() -> List[Todo]: @app.resolver(type_name="Mutation", field_name="createTodo") @tracer.capture_method def create_todo(title: str) -> Todo: - payload = ({"userId": scalar_types_utils.make_id(), "title": title, "completed": False},) # dummy UUID str + payload = {"userId": scalar_types_utils.make_id(), "title": title, "completed": False} # dummy UUID str todo: Response = requests.post("https://jsonplaceholder.typicode.com/todos", json=payload) todo.raise_for_status() From ceba04eb4017d763146ef142a4be4faebdec93e1 Mon Sep 17 00:00:00 2001 From: heitorlessa Date: Wed, 1 Mar 2023 07:16:21 +0100 Subject: [PATCH 6/9] docs: fix highlighting for app.resolve --- docs/core/event_handler/appsync.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/core/event_handler/appsync.md b/docs/core/event_handler/appsync.md index 7efc5e11eed..e5fe7093db5 100644 --- a/docs/core/event_handler/appsync.md +++ b/docs/core/event_handler/appsync.md @@ -61,7 +61,7 @@ Here's an example with two separate functions to resolve `getTodo` and `listTodo === "getting_started_graphql_api_resolver.py" - ```python hl_lines="14 21 31 33-34 43 45 53 55 70" + ```python hl_lines="14 21 31 33-34 43 45 53 55 66" --8<-- "examples/event_handler_graphql/src/getting_started_graphql_api_resolver.py" ``` From b7ef0b3bb4ecfaff9d855e677d018fb4ad9c03a6 Mon Sep 17 00:00:00 2001 From: heitorlessa Date: Wed, 1 Mar 2023 08:41:01 +0100 Subject: [PATCH 7/9] fix: infra and code example, add mutation json --- docs/core/event_handler/appsync.md | 8 ++- .../event_handler_graphql/sam/samconfig.toml | 10 ++++ .../event_handler_graphql/sam/template.yaml | 28 +++------- .../src/getting_started_create_todo.json | 53 +++++++++++++++++++ .../getting_started_graphql_api_resolver.py | 2 +- .../src/getting_started_schema.graphql | 1 + .../src/requirements.txt | 2 + 7 files changed, 81 insertions(+), 23 deletions(-) create mode 100644 examples/event_handler_graphql/sam/samconfig.toml create mode 100644 examples/event_handler_graphql/src/getting_started_create_todo.json create mode 100644 examples/event_handler_graphql/src/requirements.txt diff --git a/docs/core/event_handler/appsync.md b/docs/core/event_handler/appsync.md index e5fe7093db5..caef764d666 100644 --- a/docs/core/event_handler/appsync.md +++ b/docs/core/event_handler/appsync.md @@ -67,7 +67,7 @@ Here's an example with two separate functions to resolve `getTodo` and `listTodo === "getting_started_schema.graphql" - ```typescript hl_lines="6-8 12" + ```typescript hl_lines="7-9 13" --8<-- "examples/event_handler_graphql/src/getting_started_schema.graphql" ``` @@ -83,6 +83,12 @@ Here's an example with two separate functions to resolve `getTodo` and `listTodo --8<-- "examples/event_handler_graphql/src/getting_started_list_todos.json" ``` +=== "getting_started_create_todo.json" + + ```json + --8<-- "examples/event_handler_graphql/src/getting_started_create_todo.json" + ``` + ### Scalar functions When working with [AWS AppSync Scalar types](https://docs.aws.amazon.com/appsync/latest/devguide/scalars.html){target="_blank"}, you might want to generate the same values for data validation purposes. diff --git a/examples/event_handler_graphql/sam/samconfig.toml b/examples/event_handler_graphql/sam/samconfig.toml new file mode 100644 index 00000000000..fc5a42d082c --- /dev/null +++ b/examples/event_handler_graphql/sam/samconfig.toml @@ -0,0 +1,10 @@ +version = 0.1 +[default] +[default.deploy] +[default.deploy.parameters] +stack_name = "pt-graphql-getting-started" +s3_bucket = "aws-sam-cli-managed-default-samclisourcebucket-1pssy5gdxqcao" +s3_prefix = "pt-graphql-getting-started" +region = "eu-west-1" +capabilities = "CAPABILITY_IAM" +image_repositories = [] diff --git a/examples/event_handler_graphql/sam/template.yaml b/examples/event_handler_graphql/sam/template.yaml index 4c6ca50adc7..7639114802c 100644 --- a/examples/event_handler_graphql/sam/template.yaml +++ b/examples/event_handler_graphql/sam/template.yaml @@ -70,26 +70,12 @@ Resources: Type: "AWS::AppSync::GraphQLSchema" Properties: ApiId: !GetAtt TodosApi.ApiId - Definition: | - schema { - query:Query - } - - type Query { - getTodo(id: ID!): Todo - listTodos: [Todo] - } - - type Mutation { - createTodo(title: String!): Todo - } - - type Todo { - id: ID! - userId: String - title: String - completed: Boolean - } + DefinitionS3Location: ../src/getting_started_schema.graphql + Metadata: + cfn-lint: + config: + ignore_checks: + - W3002 # allow relative path in DefinitionS3Location # Lambda Direct Data Source and Resolver @@ -133,4 +119,4 @@ Outputs: Value: !GetAtt TodosFunction.Arn TodosApi: - Value: !GetAtt TodosApi.Arn + Value: !GetAtt TodosApi.GraphQLUrl diff --git a/examples/event_handler_graphql/src/getting_started_create_todo.json b/examples/event_handler_graphql/src/getting_started_create_todo.json new file mode 100644 index 00000000000..e8a1ce65f95 --- /dev/null +++ b/examples/event_handler_graphql/src/getting_started_create_todo.json @@ -0,0 +1,53 @@ + { + "arguments": { + "title": "Sample todo mutation" + }, + "identity": null, + "source": null, + "request": { + "headers": { + "x-forwarded-for": "203.0.113.1, 203.0.113.18", + "cloudfront-viewer-country": "NL", + "cloudfront-is-tablet-viewer": "false", + "x-amzn-requestid": "fdc4f30b-44c2-475d-b2f9-9da0778d5275", + "via": "2.0 f655cacd0d6f7c5dc935ea687af6f3c0.cloudfront.net (CloudFront)", + "cloudfront-forwarded-proto": "https", + "origin": "https://eu-west-1.console.aws.amazon.com", + "content-length": "166", + "x-forwarded-proto": "https", + "accept-language": "en-US,en;q=0.5", + "host": "kiuqayvn4jhhzio6whpnk7xj3a.appsync-api.eu-west-1.amazonaws.com", + "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:102.0) Gecko/20100101 Firefox/102.0", + "cloudfront-is-mobile-viewer": "false", + "accept": "application/json, text/plain, */*", + "cloudfront-viewer-asn": "1136", + "cloudfront-is-smarttv-viewer": "false", + "accept-encoding": "gzip, deflate, br", + "referer": "https://eu-west-1.console.aws.amazon.com/", + "content-type": "application/json", + "x-api-key": "da2-vsqnxwyzgzf4nh6kvoaidtvs7y", + "sec-fetch-mode": "cors", + "x-amz-cf-id": "0kxqijFPsbGSWJ1u3Z_sUS4Wu2hRoG_2T77aJPuoh_Q4bXAB3x0a3g==", + "x-amzn-trace-id": "Root=1-63fef2cf-6d566e9f4a35b99e6212388e", + "sec-fetch-dest": "empty", + "x-amz-user-agent": "AWS-Console-AppSync/", + "cloudfront-is-desktop-viewer": "true", + "sec-fetch-site": "cross-site", + "x-forwarded-port": "443" + }, + "domainName": null + }, + "prev": null, + "info": { + "selectionSetList": [ + "id", + "title", + "completed" + ], + "selectionSetGraphQL": "{\n id\n title\n completed\n}", + "fieldName": "createTodo", + "parentTypeName": "Mutation", + "variables": {} + }, + "stash": {} +} diff --git a/examples/event_handler_graphql/src/getting_started_graphql_api_resolver.py b/examples/event_handler_graphql/src/getting_started_graphql_api_resolver.py index 864734b8782..9edd8c68dad 100644 --- a/examples/event_handler_graphql/src/getting_started_graphql_api_resolver.py +++ b/examples/event_handler_graphql/src/getting_started_graphql_api_resolver.py @@ -57,7 +57,7 @@ def create_todo(title: str) -> Todo: todo: Response = requests.post("https://jsonplaceholder.typicode.com/todos", json=payload) todo.raise_for_status() - return todo.json()["0"] + return todo.json() @logger.inject_lambda_context(correlation_id_path=correlation_paths.APPSYNC_RESOLVER) diff --git a/examples/event_handler_graphql/src/getting_started_schema.graphql b/examples/event_handler_graphql/src/getting_started_schema.graphql index c0d1f8d4281..02d3bc3b2f3 100644 --- a/examples/event_handler_graphql/src/getting_started_schema.graphql +++ b/examples/event_handler_graphql/src/getting_started_schema.graphql @@ -1,5 +1,6 @@ schema { query: Query + mutation: Mutation } type Query { diff --git a/examples/event_handler_graphql/src/requirements.txt b/examples/event_handler_graphql/src/requirements.txt new file mode 100644 index 00000000000..76d40513e2b --- /dev/null +++ b/examples/event_handler_graphql/src/requirements.txt @@ -0,0 +1,2 @@ +aws-lambda-powertools[tracer] +requests From fe655148fff7d95c22cbd01516a9eb794628c756 Mon Sep 17 00:00:00 2001 From: heitorlessa Date: Wed, 1 Mar 2023 08:57:26 +0100 Subject: [PATCH 8/9] docs: group all events under a new tab 'sample events' --- docs/core/event_handler/appsync.md | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/docs/core/event_handler/appsync.md b/docs/core/event_handler/appsync.md index caef764d666..06471ea718e 100644 --- a/docs/core/event_handler/appsync.md +++ b/docs/core/event_handler/appsync.md @@ -71,23 +71,25 @@ Here's an example with two separate functions to resolve `getTodo` and `listTodo --8<-- "examples/event_handler_graphql/src/getting_started_schema.graphql" ``` -=== "getting_started_get_todo.json" +=== "sample events" - ```json hl_lines="2-3 42" - --8<-- "examples/event_handler_graphql/src/getting_started_get_todo.json" - ``` + === "getting_started_get_todo.json" -=== "getting_started_list_todos.json" + ```json hl_lines="2-3 42" + --8<-- "examples/event_handler_graphql/src/getting_started_get_todo.json" + ``` - ```json hl_lines="2 40" - --8<-- "examples/event_handler_graphql/src/getting_started_list_todos.json" - ``` + === "getting_started_list_todos.json" -=== "getting_started_create_todo.json" + ```json hl_lines="2 40" + --8<-- "examples/event_handler_graphql/src/getting_started_list_todos.json" + ``` - ```json - --8<-- "examples/event_handler_graphql/src/getting_started_create_todo.json" - ``` + === "getting_started_create_todo.json" + + ```json + --8<-- "examples/event_handler_graphql/src/getting_started_create_todo.json" + ``` ### Scalar functions From 7ea7c231bc967be7633d55952ae6afedfb41188c Mon Sep 17 00:00:00 2001 From: heitorlessa Date: Wed, 1 Mar 2023 08:58:32 +0100 Subject: [PATCH 9/9] docs: highlight create_todo.json --- docs/core/event_handler/appsync.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/core/event_handler/appsync.md b/docs/core/event_handler/appsync.md index 06471ea718e..14a638b6123 100644 --- a/docs/core/event_handler/appsync.md +++ b/docs/core/event_handler/appsync.md @@ -87,7 +87,7 @@ Here's an example with two separate functions to resolve `getTodo` and `listTodo === "getting_started_create_todo.json" - ```json + ```json hl_lines="2 48 49" --8<-- "examples/event_handler_graphql/src/getting_started_create_todo.json" ```