Define your custom business logic in a Lambda function resolver, HTTP resolver, or an AppSync JavaScript or VTL resolver and expose them in a GraphQL query or mutation. Extend or override Amplify-generated GraphQL resolvers to optimize for your specific use cases.
Create a custom query or mutationWhile @model
automatically generates dedicated "create", "read", "update", "delete", and "subscription" queries or mutations for you, there are some cases where you want to define a stand-alone query or mutation.
Use one of these resolver choices to handle the query or mutation request:
Secure your custom query or mutation with field-level authorization rules
The @function
directive allows you to quickly & easily configure a AWS Lambda resolvers with your GraphQL API. You can use any AWS Lambda functions that was created with the Amplify CLI, AWS CDK or reference an existing AWS Lambda function created with any other means.
For example, use amplify add function
to add a Lambda function called "echofunction" with the following handler:
To connect an AWS Lambda resolver to the GraphQL API, add the @function
directive to a field in your schema.
The Amplify CLI provides support for maintaining multiple environments. When you deploy a function via amplify add function
, it will automatically add the environment suffix to your Lambda function name. For example, if you create a function named echofunction
using amplify add function
in the dev
environment, the deployed function will be named echofunction-dev
. The @function
directive allows you to use ${env}
to reference the current Amplify CLI environment.
First, create your Lambda function in CDK with your logic and set the functionName
parameter.
To connect an AWS Lambda resolver to the GraphQL API, add the @function
directive to a field in your GraphQL schema.
Optionally, if you don't want to hard-code the function name into the GraphQL schema, you can also set an arbitrary name in the GraphQL schema and then map a function within CDK to the function name.
If you deployed your Lambda function without Amplify CLI then you must provide the full Lambda function name in the name
parameter. If you deployed the same function with the name echofunction then you would have:
When writing Lambda functions that are connected via the @function
directive, you can expect the following structure for the AWS Lambda event
object.
Your function should follow the Lambda handler guidelines for your specific language. See the developer guides from the AWS Lambda documentation for your chosen language. If you choose to use structured types, your type should serialize the AWS Lambda event object outlined above. For example, if using Golang, you should define a struct with the above fields.
Calling functions in different regionsBy default, you expect the function to be in the same region as the Amplify project. If you need to call a function in a different or a specific region, you can provide the region argument.
Calling functions in different AWS accounts is not supported via the @function
directive but is supported by AWS AppSync.
You can chain together multiple @function
resolvers such that they are invoked in series when your field's resolver is invoked. To create a pipeline resolver that calls to multiple AWS Lambda functions in series, use multiple @function
directives on the field. Similarly, @function
can be combined with field-level @auth
. When combining these field directives, the ordering in the schema matches the ordering in the pipeline resolver. You can choose to have functions before and/or after field level authorization is applied.
Note: Be careful when using @auth directives on a field in a root type. @auth directives on field definitions use the source object to perform authorization logic and the source will be an empty object for fields on root types. Static group authorization should perform as expected.
In the example above when you run a mutation that calls the Mutation.doSomeWork
field, the worker-function will be invoked first then the audit-function will be invoked with an event that contains the results of the worker-function under the event.prev.result key. The audit-function would need to return event.prev.result if you want the result of worker-function to be returned for the field.
Definition of @function
directive:
Under the hood, Amplify creates an AppSync::FunctionConfiguration
for each unique instance of @function
in a document and a pipeline resolver containing a pointer to a function for each @function
on a given field.
The @function
directive generates these resources as necessary:
The @http
directive allows you to quickly configure HTTP resolvers within your GraphQL API.
To connect to an endpoint, add the @http directive to a field in your GraphQL schema. The directive allows you to define URL path parameters, and specify a query string and/or specify a request body. For example, given the definition of a Post type:
Amplify generates the definition below that sends a request to the url when the listPosts query is used.
The @http
directive generates resolvers that can handle XML and JSON responses. If an HTTP method is not defined, GET
is used. You can specify a list of static headers to be passed with the HTTP requests to your backend in your directive definition.
You can create dynamic paths by specifying parameters in the directive URL by using the special :<parameter>
notation. Your set of parameters can then be specified in the params input object of the query. Note that path parameters are not added to the request body or query string. You can define multiple parameters.
In the example above, the :id
parameter will generate the appropriate query input as shown below:
You can fetch a specific post by enclosing the id in the params input object.
This executes the following request:
Query StringYou can send a query string with your request by specifying variables for your query. The query string is supported with all request methods.
Given the definition
Amplify generates
You can query for posts using the query
input object
which sends the following request:
Request BodyThe @http
directive also allows you to specify the body of a request, which is used for POST
, PUT
, and PATCH
requests. To create a new post, you can define the following.
Amplify generates the addPost
query field with the query
and body
input objects since this type of request also supports a query string. The generated resolver verifies that non-null arguments (e.g.: the title
and description
) are passed in at least one of the input objects; if not, an error is returned.
You can add a post by using the body
input object:
which will send
Reference Amplify environment nameThe @http
directive allows you to use ${env}
to reference the current Amplify CLI environment.
which, in the DEV
environment, will send
Combining the different components
You can use a combination of parameters, query, body, headers, and environments in your @http
directive definition.
Given the definition
you can update a post with
which, in the DEV
environment, will send
In some cases, you may want to send a request based on existing field data. Take a scenario where you have a post and want to fetch comments associated with the post in a single query. Let's use the previous definition of Post
and Comment
.
A post can be fetched at /posts/:id
and a post's comments at /posts/:id/comments
. You can fetch the comments based on the post id with the following updated definition. $ctx.source
is a map that contains the resolution of the parent field (Post
) and gives access to id
.
You can retrieve the comments of a specific post with the following query and selection set.
Assuming that getPost
retrieves a post with the id POST_ID
, the comments field is resolved by sending this request to the endpoint
Note that there is no check to ensure that the reference variable (here the post ID) exists. When using this technique, it is recommended to make sure the referenced field is non-null.
How it worksDefinition of @http
directive:
The @http
transformer will create one HTTP datasource for each identified base URL. For example, if multiple HTTP resolvers are created that interact with the "https://www.example.com" endpoint, only a single datasource is created. Each directive generates one resolver. Depending on the definition, the appropriate body
, params
, and query
input types are created. Note that @http
transformer does not support calling other AWS services where Signature Version 4 signing process is required.
You can use AWS Cloud Development Kit (CDK) to define custom AppSync resolvers for your GraphQL API. @auth
directives are not supported for custom queries or mutations that are connected to a JavaScript or VTL resolver. This is because you are replacing Amplify's auto-generated capabilities for that particular query or mutation with a custom-defined cloud resources.
? How do you want to define this custom resource?
? Provide a name for your custom resource
Next, install the AppSync dependencies for your custom resource:
Note: Installations using the '~' character do not modify the package.json. To use '~' for default npm configurations, make sure your package.json reflects the right dependency to avoid compatibility errors in CDK.
Finally, add your custom resolvers into the cdk-stack.ts
file. You can either add the JavaScript or VTL inline into your cdk-stack.ts
file.
Review the Resolver Mapping Template Programming Guide to learn more about the VTL template.
Pipeline ResolverNote: Users moving from ElasticSearch to OpenSearch will need to change the datasource name from
ElasticSearchDomain
toOpenSearchDataSource
if the upgrade process changes the source name. For new @searchable models the datasource name will default toOpenSearchDataSource
.
You can alternatively define the VTL templates in another file such as Query.querySomething.req.vtl
or Query.querySomething.res.vtl
in amplify/backend/custom/MyCustomResolvers/
. Then use the following code snippets to retrieve them:
Note: the
..
is added to the path because the path is always relative to thebuild
folder of the custom resource.
Authorization rules can be applied with the @auth
directive in the same way as field-level authorization rules. See Field-level authorization rules for details.
In the example below, myCustomMutation
can only be executed by signed-in customers who are authenticated with IAM:
Override Amplify-generated resolversKnown limitation: You can't combine the
@auth
directive with a custom query or mutation that is using a VTL resolver.
Amplify generates AWS AppSync pipeline resolver for your queries and mutations. The resolvers are listed the following API resource's folder amplify/backend/api/<resource_name>/build/resolvers/
.
To override an Amplify-generated resolver:
build/resolvers
.vtl
with the same file name the resource's resolvers/
(not under build/
)amplify api gql-compile
or amplify push
the Amplify-generated resolver file will be replaced with your overwritten resolver fileamplify/backend/api/<resource_name>
â  âââ resolvers
â  â  âââ ...
â  â  âââ Query.searchTodos.req.vtl # Find resolver file name
â  â  âââ ...
â  âââ Query.searchTodos.req.vtl # Place resolver overrides with the same file name here
The example above shows how the Query.searchTodos.req.vtl
is overwritten with a custom resolver. Review the Resolver Mapping Template Programming Guide to learn more about the VTL template.
Amplify generates AWS AppSync pipeline resolvers for your queries and mutations. You can "slot" in your custom business logic between Amplify-generated resolvers. You can find Amplify-generated resolvers under your API resources' build/resolvers/
folder. The resolver functions file name determines its placement within the slot sequence.
[Query|Mutation|Subscription].[field name].[slot name].[slot placement].[req|res].vtl
Mutation.createTodo.postAuth.1.req.vtl
To extend an Amplify-generated resolver:
.vtl
file with the correct the file naming convention into resolvers/
(not under build/
)amplify api gql-compile
or amplify push
the Amplify-generated resolver file will be replaced within the desired slot within the resolver sequence.amplify/backend/api/<resource_name>
â  âââ resolvers
â  â  âââ ...
â  â  âââ Mutation.createTodo.postAuth.1.req.vtl # Amplify-generated resolvers
â  â  âââ ...
â  âââ Mutation.createTodo.postAuth.2.req.vtl # Custom resolver slotted in after postAuth.1 resolver
For example, the a resolver function file named Mutation.createTodo.postAuth.2.req.vtl
will be slotted in right after the Mutation.createTodo.postAuth.1.req.vtl
resolver. Review the Resolver Mapping Template Programming Guide to learn more about the VTL template.
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4