From 57bbdc8c05ccdc393a5e900d5dd7ff41689075a2 Mon Sep 17 00:00:00 2001 From: Varshitha Pamisetty Date: Mon, 26 Oct 2026 13:34:16 +0100 Subject: [PATCH 1/2] fix(data): add native client examples to connect HTTP datasource page --- .../connect-http-datasource/index.mdx | 450 ++++++++++++++++++ 1 file changed, 450 insertions(+) diff --git a/src/pages/[platform]/build-a-backend/data/custom-business-logic/connect-http-datasource/index.mdx b/src/pages/[platform]/build-a-backend/data/custom-business-logic/connect-http-datasource/index.mdx index b8f531bf2f5..f435f789dd8 100644 --- a/src/pages/[platform]/build-a-backend/data/custom-business-logic/connect-http-datasource/index.mdx +++ b/src/pages/[platform]/build-a-backend/data/custom-business-logic/connect-http-datasource/index.mdx @@ -395,6 +395,8 @@ export function response(ctx) { ## Step 5 - Invoke custom queries or mutations + + From your generated Data client, you can find all your custom queries and mutations under the client.queries. and client.mutations. APIs respectively. @@ -431,6 +433,454 @@ const { data, errors } = await client.mutations.deletePost({ + + + + +From your client code, you can create a custom GraphQL request for each custom query and mutation. First define a type that matches the `Post` return type: + +```swift +struct Post: Codable { + public let title: String? + public let content: String? + public let author: String +} +``` + + + +```swift +struct AddPostResponse: Codable { + public let addPost: Post +} + +let document = """ + mutation AddPost($title: String, $content: String, $author: String!) { + addPost(title: $title, content: $content, author: $author) { + title + content + author + } + } + """ + +let result = try await Amplify.API.mutate(request: GraphQLRequest( + document: document, + variables: [ + "title": "My Post", + "content": "My Content", + "author": "Chris" + ], + responseType: AddPostResponse.self +)) +switch result { +case .success(let response): + print(response.addPost) +case .failure(let error): + print(error) +} +``` + + +```swift +struct GetPostResponse: Codable { + public let getPost: Post +} + +let document = """ + query GetPost($id: ID!) { + getPost(id: $id) { + title + content + author + } + } + """ + +let result = try await Amplify.API.query(request: GraphQLRequest( + document: document, + variables: [ + "id": "" + ], + responseType: GetPostResponse.self +)) +switch result { +case .success(let response): + print(response.getPost) +case .failure(let error): + print(error) +} +``` + + +```swift +struct UpdatePostResponse: Codable { + public let updatePost: Post +} + +let document = """ + mutation UpdatePost($id: ID!, $title: String) { + updatePost(id: $id, title: $title) { + title + content + author + } + } + """ + +let result = try await Amplify.API.mutate(request: GraphQLRequest( + document: document, + variables: [ + "id": "", + "title": "An Updated Post" + ], + responseType: UpdatePostResponse.self +)) +switch result { +case .success(let response): + print(response.updatePost) +case .failure(let error): + print(error) +} +``` + + +```swift +struct DeletePostResponse: Codable { + public let deletePost: Post +} + +let document = """ + mutation DeletePost($id: ID!) { + deletePost(id: $id) { + title + content + author + } + } + """ + +let result = try await Amplify.API.mutate(request: GraphQLRequest( + document: document, + variables: [ + "id": "" + ], + responseType: DeletePostResponse.self +)) +switch result { +case .success(let response): + print(response.deletePost) +case .failure(let error): + print(error) +} +``` + + + + + + + +From your client code, you can create a custom GraphQL request for each custom query and mutation. First define a data class that matches the `Post` return type: + +```kotlin +data class Post( + val title: String?, + val content: String?, + val author: String +) +``` + + + +```kotlin +data class AddPostResponse( + val addPost: Post +) + +val document = """ + mutation AddPost(${'$'}title: String, ${'$'}content: String, ${'$'}author: String!) { + addPost(title: ${'$'}title, content: ${'$'}content, author: ${'$'}author) { + title + content + author + } + } +""".trimIndent() + +val request = SimpleGraphQLRequest( + document, + mapOf( + "title" to "My Post", + "content" to "My Content", + "author" to "Chris" + ), + String::class.java, + GsonVariablesSerializer()) + +Amplify.API.mutate( + request, + { + var gson = Gson() + val response = gson.fromJson(it.data, AddPostResponse::class.java) + Log.i("MyAmplifyApp", "${response.addPost}") + }, + { Log.e("MyAmplifyApp", "Mutation failed", it) } +) +``` + + +```kotlin +data class GetPostResponse( + val getPost: Post +) + +val document = """ + query GetPost(${'$'}id: ID!) { + getPost(id: ${'$'}id) { + title + content + author + } + } +""".trimIndent() + +val request = SimpleGraphQLRequest( + document, + mapOf( + "id" to "" + ), + String::class.java, + GsonVariablesSerializer()) + +Amplify.API.query( + request, + { + var gson = Gson() + val response = gson.fromJson(it.data, GetPostResponse::class.java) + Log.i("MyAmplifyApp", "${response.getPost}") + }, + { Log.e("MyAmplifyApp", "Query failed", it) } +) +``` + + +```kotlin +data class UpdatePostResponse( + val updatePost: Post +) + +val document = """ + mutation UpdatePost(${'$'}id: ID!, ${'$'}title: String) { + updatePost(id: ${'$'}id, title: ${'$'}title) { + title + content + author + } + } +""".trimIndent() + +val request = SimpleGraphQLRequest( + document, + mapOf( + "id" to "", + "title" to "An Updated Post" + ), + String::class.java, + GsonVariablesSerializer()) + +Amplify.API.mutate( + request, + { + var gson = Gson() + val response = gson.fromJson(it.data, UpdatePostResponse::class.java) + Log.i("MyAmplifyApp", "${response.updatePost}") + }, + { Log.e("MyAmplifyApp", "Mutation failed", it) } +) +``` + + +```kotlin +data class DeletePostResponse( + val deletePost: Post +) + +val document = """ + mutation DeletePost(${'$'}id: ID!) { + deletePost(id: ${'$'}id) { + title + content + author + } + } +""".trimIndent() + +val request = SimpleGraphQLRequest( + document, + mapOf( + "id" to "" + ), + String::class.java, + GsonVariablesSerializer()) + +Amplify.API.mutate( + request, + { + var gson = Gson() + val response = gson.fromJson(it.data, DeletePostResponse::class.java) + Log.i("MyAmplifyApp", "${response.deletePost}") + }, + { Log.e("MyAmplifyApp", "Mutation failed", it) } +) +``` + + + + + + + +From your client code, you can create a custom GraphQL request for each custom query and mutation. First define a class that matches the `Post` return type: + +```dart +class Post { + final String? title; + final String? content; + final String author; + + Post({this.title, this.content, required this.author}); + + factory Post.fromJson(Map json) { + return Post( + title: json['title'], + content: json['content'], + author: json['author'], + ); + } +} +``` + + + +```dart +import 'dart:convert'; + +const graphQLDocument = ''' + mutation AddPost(\$title: String, \$content: String, \$author: String!) { + addPost(title: \$title, content: \$content, author: \$author) { + title + content + author + } + } +'''; + +final request = GraphQLRequest( + document: graphQLDocument, + variables: { + 'title': 'My Post', + 'content': 'My Content', + 'author': 'Chris', + }, +); + +final response = await Amplify.API.mutate(request: request).response; + +Map jsonMap = json.decode(response.data!); +final post = Post.fromJson(jsonMap['addPost']); +safePrint(post.author); +``` + + +```dart +import 'dart:convert'; + +const graphQLDocument = ''' + query GetPost(\$id: ID!) { + getPost(id: \$id) { + title + content + author + } + } +'''; + +final request = GraphQLRequest( + document: graphQLDocument, + variables: { + 'id': '', + }, +); + +final response = await Amplify.API.query(request: request).response; + +Map jsonMap = json.decode(response.data!); +final post = Post.fromJson(jsonMap['getPost']); +safePrint(post.author); +``` + + +```dart +import 'dart:convert'; + +const graphQLDocument = ''' + mutation UpdatePost(\$id: ID!, \$title: String) { + updatePost(id: \$id, title: \$title) { + title + content + author + } + } +'''; + +final request = GraphQLRequest( + document: graphQLDocument, + variables: { + 'id': '', + 'title': 'An Updated Post', + }, +); + +final response = await Amplify.API.mutate(request: request).response; + +Map jsonMap = json.decode(response.data!); +final post = Post.fromJson(jsonMap['updatePost']); +safePrint(post.author); +``` + + +```dart +import 'dart:convert'; + +const graphQLDocument = ''' + mutation DeletePost(\$id: ID!) { + deletePost(id: \$id) { + title + content + author + } + } +'''; + +final request = GraphQLRequest( + document: graphQLDocument, + variables: { + 'id': '', + }, +); + +final response = await Amplify.API.mutate(request: request).response; + +Map jsonMap = json.decode(response.data!); +final post = Post.fromJson(jsonMap['deletePost']); +safePrint(post.author); +``` + + + + + ## Conclusion In this guide, you’ve added an external REST API as a HTTP data source to an Amplify Data API and defined custom queries and mutations, handled by AppSync JS resolvers, to manipulate Post items in an external REST API using the Amplify Gen 2 Data client. From 068e14dffc80d74a761bff6d06a23a2b74cef549 Mon Sep 17 00:00:00 2001 From: Varshitha Pamisetty Date: Tue, 27 Oct 2026 16:06:42 +0100 Subject: [PATCH 2/2] fix(data): check GraphQL errors before parsing in native examples --- .../connect-http-datasource/index.mdx | 80 +++++++++++++------ 1 file changed, 56 insertions(+), 24 deletions(-) diff --git a/src/pages/[platform]/build-a-backend/data/custom-business-logic/connect-http-datasource/index.mdx b/src/pages/[platform]/build-a-backend/data/custom-business-logic/connect-http-datasource/index.mdx index f435f789dd8..c0aaea5302c 100644 --- a/src/pages/[platform]/build-a-backend/data/custom-business-logic/connect-http-datasource/index.mdx +++ b/src/pages/[platform]/build-a-backend/data/custom-business-logic/connect-http-datasource/index.mdx @@ -621,9 +621,13 @@ val request = SimpleGraphQLRequest( Amplify.API.mutate( request, { - var gson = Gson() - val response = gson.fromJson(it.data, AddPostResponse::class.java) - Log.i("MyAmplifyApp", "${response.addPost}") + if (it.hasErrors()) { + Log.e("MyAmplifyApp", "Mutation returned errors: ${it.errors}") + } else { + var gson = Gson() + val response = gson.fromJson(it.data, AddPostResponse::class.java) + Log.i("MyAmplifyApp", "${response.addPost}") + } }, { Log.e("MyAmplifyApp", "Mutation failed", it) } ) @@ -656,9 +660,13 @@ val request = SimpleGraphQLRequest( Amplify.API.query( request, { - var gson = Gson() - val response = gson.fromJson(it.data, GetPostResponse::class.java) - Log.i("MyAmplifyApp", "${response.getPost}") + if (it.hasErrors()) { + Log.e("MyAmplifyApp", "Query returned errors: ${it.errors}") + } else { + var gson = Gson() + val response = gson.fromJson(it.data, GetPostResponse::class.java) + Log.i("MyAmplifyApp", "${response.getPost}") + } }, { Log.e("MyAmplifyApp", "Query failed", it) } ) @@ -692,9 +700,13 @@ val request = SimpleGraphQLRequest( Amplify.API.mutate( request, { - var gson = Gson() - val response = gson.fromJson(it.data, UpdatePostResponse::class.java) - Log.i("MyAmplifyApp", "${response.updatePost}") + if (it.hasErrors()) { + Log.e("MyAmplifyApp", "Mutation returned errors: ${it.errors}") + } else { + var gson = Gson() + val response = gson.fromJson(it.data, UpdatePostResponse::class.java) + Log.i("MyAmplifyApp", "${response.updatePost}") + } }, { Log.e("MyAmplifyApp", "Mutation failed", it) } ) @@ -727,9 +739,13 @@ val request = SimpleGraphQLRequest( Amplify.API.mutate( request, { - var gson = Gson() - val response = gson.fromJson(it.data, DeletePostResponse::class.java) - Log.i("MyAmplifyApp", "${response.deletePost}") + if (it.hasErrors()) { + Log.e("MyAmplifyApp", "Mutation returned errors: ${it.errors}") + } else { + var gson = Gson() + val response = gson.fromJson(it.data, DeletePostResponse::class.java) + Log.i("MyAmplifyApp", "${response.deletePost}") + } }, { Log.e("MyAmplifyApp", "Mutation failed", it) } ) @@ -787,9 +803,13 @@ final request = GraphQLRequest( final response = await Amplify.API.mutate(request: request).response; -Map jsonMap = json.decode(response.data!); -final post = Post.fromJson(jsonMap['addPost']); -safePrint(post.author); +if (response.hasErrors) { + safePrint('errors: ${response.errors}'); +} else { + Map jsonMap = json.decode(response.data!); + final post = Post.fromJson(jsonMap['addPost']); + safePrint(post.author); +} ``` @@ -815,9 +835,13 @@ final request = GraphQLRequest( final response = await Amplify.API.query(request: request).response; -Map jsonMap = json.decode(response.data!); -final post = Post.fromJson(jsonMap['getPost']); -safePrint(post.author); +if (response.hasErrors) { + safePrint('errors: ${response.errors}'); +} else { + Map jsonMap = json.decode(response.data!); + final post = Post.fromJson(jsonMap['getPost']); + safePrint(post.author); +} ``` @@ -844,9 +868,13 @@ final request = GraphQLRequest( final response = await Amplify.API.mutate(request: request).response; -Map jsonMap = json.decode(response.data!); -final post = Post.fromJson(jsonMap['updatePost']); -safePrint(post.author); +if (response.hasErrors) { + safePrint('errors: ${response.errors}'); +} else { + Map jsonMap = json.decode(response.data!); + final post = Post.fromJson(jsonMap['updatePost']); + safePrint(post.author); +} ``` @@ -872,9 +900,13 @@ final request = GraphQLRequest( final response = await Amplify.API.mutate(request: request).response; -Map jsonMap = json.decode(response.data!); -final post = Post.fromJson(jsonMap['deletePost']); -safePrint(post.author); +if (response.hasErrors) { + safePrint('errors: ${response.errors}'); +} else { + Map jsonMap = json.decode(response.data!); + final post = Post.fromJson(jsonMap['deletePost']); + safePrint(post.author); +} ```