@@ -53,7 +53,7 @@ export const sayHello = defineFunction({
5353Next, create the corresponding handler file at ` amplify/functions/say-hello/handler.ts ` . This is where your function code will go.
5454
5555``` ts title="amplify/functions/say-hello/handler.ts"
56- import { Handler } from ' aws-lambda' ;
56+ import type { Handler } from ' aws-lambda' ;
5757
5858export const handler: Handler = async (event , context ) => {
5959 // your function code goes here
@@ -76,7 +76,209 @@ defineBackend({
7676});
7777```
7878
79- Now when you run ` npx ampx sandbox ` or deploy your app on Amplify, it will include your backend function. See the [ examples] ( ../examples/ ) below for connecting your functions to event sources.
79+ Now when you run ` npx ampx sandbox ` or deploy your app on Amplify, it will include your Function.
80+
81+ To invoke your Function, we recommend adding your [ Function as a handler for a custom query with your Amplify Data resource] ( /[platform]/build-a-backend/data/custom-business-logic/ ) . This will enable you to strongly type Function arguments and the return statement, and use this to author your Function's business logic. To get started, open your ` amplify/data/resource.ts ` file and specify a new query in your schema:
82+
83+ ``` ts title="amplify/data/resource.ts"
84+ import { type ClientSchema , a , defineData } from " @aws-amplify/backend"
85+ import { sayHello } from " ../functions/say-hello/resource"
86+
87+ const schema = a .schema ({
88+ // highlight-start
89+ sayHello: a
90+ .query ()
91+ .arguments ({
92+ name: a .string ().default (" World" ),
93+ })
94+ .returns (a .string ())
95+ .handler (a .handler .function (sayHello )),
96+ // highlight-end
97+ })
98+
99+ export type Schema = ClientSchema <typeof schema >
100+
101+ export const data = defineData ({
102+ schema ,
103+ authorizationModes: {
104+ defaultAuthorizationMode: " iam" ,
105+ },
106+ })
107+ ```
108+
109+ Now you can use this query from the ` Schema ` export to strongly type your Function handler:
110+
111+ ``` ts title="amplify/functions/say-hello/handler.ts"
112+ import type { Schema } from " ../../data/resource"
113+
114+ export const handler: Schema [" sayHello" ][" functionHandler" ] = async (event ) => {
115+ // arguments typed from `.arguments()`
116+ const { name } = event .arguments
117+ // return typed from `.returns()`
118+ return ` Hello, ${name }! `
119+ }
120+ ```
121+
122+ Finally, use the data client to invoke your Function by calling its associated query.
123+
124+ <InlineFilter filters = { [" angular" , " javascript" , " nextjs" , " react" , " react-native" , " vue" ]} >
125+
126+ ``` ts title="src/main.ts"
127+ import type { Schema } from " ./amplify/data/resource"
128+ import { Amplify } from " aws-amplify"
129+ import { generateClient } from " aws-amplify/api"
130+ import outputs from " ./amplify_outputs.json"
131+
132+ Amplify .configure (outputs )
133+
134+ const client = generateClient <Schema >()
135+
136+ // highlight-start
137+ client .queries .sayHello ({
138+ name: " Amplify" ,
139+ })
140+ // highlight-end
141+ ```
142+
143+ </InlineFilter >
144+ <InlineFilter filters = { [" android" ]} >
145+
146+ ``` kt
147+ data class SayHelloDetails (
148+ val name : String ,
149+ )
150+
151+ data class SayHelloResponse (
152+ val sayHello : SayHelloDetails
153+ )
154+
155+ val document = """
156+ query SayHelloQuery(${' $' } name: String!) {
157+ sayHello(name: ${' $' } name) {
158+ name
159+ executionDuration
160+ }
161+ }
162+ """ .trimIndent()
163+ val sayHelloQuery = SimpleGraphQLRequest <String >(
164+ document,
165+ mapOf (" name" to " Amplify" ),
166+ String ::class .java,
167+ GsonVariablesSerializer ())
168+
169+ Amplify .API .query(
170+ sayHelloQuery,
171+ {
172+ var gson = Gson ()
173+ val response = gson.fromJson(it.data, SayHelloResponse ::class .java)
174+ Log .i(" MyAmplifyApp" , " ${response.sayHello.name} " )
175+ },
176+ { Log .e(" MyAmplifyApp" , " $it " )}
177+ )
178+ ```
179+
180+ </InlineFilter >
181+ <InlineFilter filters = { [" flutter" ]} >
182+
183+ First define a class that matches your response shape:
184+
185+ ``` dart
186+ class SayHelloResponse {
187+ final SayHello sayHello;
188+
189+ SayHelloResponse({required this.sayHello});
190+
191+ factory SayHelloResponse.fromJson(Map<String, dynamic> json) {
192+ return SayHelloResponse(
193+ sayHello: SayHello.fromJson(json['sayHello']),
194+ );
195+ }
196+ }
197+
198+ class SayHello {
199+ final String name;
200+ final double executionDuration;
201+
202+ SayHello({required this.name, required this.executionDuration});
203+
204+ factory SayHello.fromJson(Map<String, dynamic> json) {
205+ return SayHello(
206+ name: json['name'],
207+ executionDuration: json['executionDuration'],
208+ );
209+ }
210+ }
211+ ```
212+
213+ Next, make the request and map the response to the classes defined above:
214+
215+ ``` dart
216+ // highlight-next-line
217+ import 'dart:convert';
218+
219+ // highlight-start
220+ const graphQLDocument = '''
221+ query SayHello(\$name: String!) {
222+ sayHello(name: \$name) {
223+ name
224+ executionDuration
225+ }
226+ }
227+ ''';
228+
229+ final echoRequest = GraphQLRequest<String>(
230+ document: graphQLDocument,
231+ variables: <String, String>{"name": "Amplify"},
232+ );
233+
234+ final response =
235+ await Amplify.API.query(request: echoRequest).response;
236+ safePrint(response);
237+
238+ Map<String, dynamic> jsonMap = json.decode(response.data!);
239+ SayHelloResponse SayHelloResponse = SayHelloResponse.fromJson(jsonMap);
240+ safePrint(SayHelloResponse.sayHello.name);
241+ // highlight-end
242+ ```
243+
244+ </InlineFilter >
245+ <InlineFilter filters = { [" swift" ]} >
246+
247+ ``` swift
248+ struct SayHelloResponse : Codable {
249+ public let sayHello: SayHello
250+
251+ struct SayHello : Codable {
252+ public let name: String
253+ public let executionDuration: Float
254+ }
255+ }
256+
257+ let document = """
258+ query EchoQuery($name: String!) {
259+ sayHello(name: $name) {
260+ name
261+ executionDuration
262+ }
263+ }
264+ """
265+
266+ let result = try await Amplify.API .query (request : GraphQLRequest< SayHelloResponse> (
267+ document : document,
268+ variables : [
269+ " name" : " Amplify"
270+ ],
271+ responseType : SayHelloResponse.self
272+ ))
273+ switch result {
274+ case .success (let response):
275+ print (response.sayHello )
276+ case .failure (let error):
277+ print (error)
278+ }
279+ ```
280+
281+ </InlineFilter >
80282
81283## Next steps
82284
0 commit comments