Page updated Mar 12, 2024

Grant Lambda function access to API and Data

Function access to defineData can be configured using an authorization rule on the schema object.

amplify/data/resource.ts
1import {
2 a,
3 defineData,
4 defineFunction,
5 type ClientSchema
6} from '@aws-amplify/backend';
7
8const functionWithDataAccess = defineFunction({
9 entry: '../functions/data-access.ts'
10});
11
12const schema = a
13 .schema({
14 Todo: a.model({
15 name: a.string(),
16 description: a.string()
17 })
18 })
19 .authorization([a.allow.resource(functionWithDataAccess)]);
20
21export type Schema = ClientSchema<typeof schema>;
22
23export const data = defineData({
24 schema
25});

The object returned from defineFunction can be passed directly to a.allow.resource() in the schema authorization rules. This will grant the function the ability to execute Query, Mutation, and Subscription operations against the GraphQL API. Use the .to() method to narrow down access to one or more operations.

1const schema = a
2 .schema({
3 Todo: a.model({
4 name: a.string(),
5 description: a.string()
6 })
7 })
8 .authorization([
9 a.allow.resource(functionWithDataAccess).to(['query', 'listen'])
10 ]); // allow query and subscription operations but not mutations

When configuring function access, the function will be provided the API endpoint as an environment variable named <defineDataName>_GRAPHQL_ENDPOINT. The default name is amplifyData_GRAPHQL_ENDPOINT unless you have specified a different name in defineData.

Function access can only be configured on the schema object. It cannot be configured on individual models or fields.

Access the API using aws-amplify

Under active development: Configuring the aws-amplify data client is under active development. The current experience has rough edges and may change between versions of @aws-amplify/backend. Try it out and provide feedback at https://github.com/aws-amplify/amplify-backend/issues/new/choose

In the handler file for your function, configure the Amplify data client

amplify/functions/data-access.ts
1import { Amplify } from 'aws-amplify';
2import { generateClient } from 'aws-amplify/data';
3import { Schema } from '../data/resource';
4import { env } from '@env/<data-access>'; // replace with your function name
5// see instructions below on copying this file
6import { modelIntrospection } from './amplifyconfiguration.json';
7
8Amplify.configure(
9 {
10 API: {
11 GraphQL: {
12 endpoint: env.<amplifyData>_GRAPHQL_ENDPOINT, // replace with your defineData name
13 region: env.AWS_REGION,
14 defaultAuthMode: 'iam',
15 modelIntrospection: modelIntrospection as never
16 }
17 }
18 },
19 {
20 Auth: {
21 credentialsProvider: {
22 getCredentialsAndIdentityId: async () => ({
23 credentials: {
24 accessKeyId: env.AWS_ACCESS_KEY_ID,
25 secretAccessKey: env.AWS_SECRET_ACCESS_KEY,
26 sessionToken: env.AWS_SESSION_TOKEN,
27 },
28 }),
29 clearCredentialsAndIdentityId: () => {
30 /* noop */
31 },
32 },
33 },
34 }
35);
36
37const dataClient = generateClient<Schema>();
38
39export const handler = async (event) => {
40 // your function code goes here
41}

The amplifyconfiguration.json file is not automatically accessible to your function. To include it with your function, you must first do a deployment of your backend using either npx amplify sandbox or Amplify hosting. Then copy the amplifyconfiguration.json file that is placed in your project root into your function directory. Now you can import the file into your function as shown above.

Note: Whenever you update your data model, you will need to copy the amplifyconfiguration.json file again.

Once you have configured the Amplify data client, you can take full advantage of the automatic typing and other model operations on the data client. The following code creates a todo and then lists all todos.

amplify/functions/data-access.ts
1const dataClient = generateClient<Schema>();
2
3export const handler = async (event) => {
4 await dataClient.models.Todo.create({
5 content: 'learn how to use the data client in a function'
6 });
7
8 const { data: allTodos, errors } = await dataClient.models.Todo.list();
9
10 if (errors) {
11 throw new Error(errors.join(', '));
12 }
13
14 return {
15 allTodos
16 };
17};