Search code examples
typescriptamazon-web-servicesaws-amplify

Saving a record using generateClient from amplify in mutation function


I'm using the Gen 2 amplify config and I have created a schema with the following model

export const NewsletterMail = a
  .model({
    id: a.string(),
    email: a.email().required(),
    confirmed: a.boolean().default(false),
  })
  .identifier(["email"])
  .authorization((allow) => [allow.publicApiKey()]);

Now I've also added a mutation handler function in where I call an external api to send the email (which works just fine), but I want to first save the email in the model above.

How is this done?

I've tried by adding the generateClient this into the handler function:

import amplifyConfig from "../../../amplify_outputs.json";
...
export const handler = async (event) => {
  Amplify.configure(amplifyConfig);
  const client = generateClient<Schema>();

  const emailCreatedResponse = await client.models.NewsletterMail.create({
    email: event.arguments.email,
  });
... send email api logic ...
}

But since the amplify_outputs are generated, it only works on local with the generated amplify_outputs it does not work when deployed.

Any suggestion on how to pass the generated amplify_outputs.json on deploy to the function?


Solution

  • Your outputs are generated in your deployment build also. You should post what error/s you're getting. But, you are probably having an issue with creating the client in a lambda (your function).

    For accessing the client in a lambda, you can use getAmplifyDataClientConfig:

    import { env } from '$amplify/env/yourFunctionName';
    import { getAmplifyDataClientConfig } from '@aws-amplify/backend/function/runtime';
    import { Amplify } from 'aws-amplify';
    import { generateClient } from 'aws-amplify/data';
    import { type Schema } from "../../data/resource";
    
    const { resourceConfig, libraryOptions } = await getAmplifyDataClientConfig(env);
    
    Amplify.configure(resourceConfig, libraryOptions);
    
    const client = generateClient<Schema>();
    

    Note, you also need to grant access for your function in your backend for this to work:

    .schema({.....}).authorization((allow) => [allow.resource(yourFunctionName)]);