I used Amplify to generate a static website and the underlying React app. Initially I also generated an API endpoint but, because my lambda function may run over the API Gateway timeout limit (29 seconds), I need to invoke the lambda function directly from the generated React App, instead of going through API Gateway.
The code looks as follows, for the React page to authenticate using Cognito:
import Auth from '@aws-amplify/auth';
import { withAuthenticator } from 'aws-amplify-react';
import awsconfig from './aws-exports';
Auth.configure(awsconfig);
The above lines wrap the App (root) object and work as advertised. But since I do not want to use the API Gateway, how do I invoke the AWS Lambda function directly from React App?
The answers I could find talk about importing AWS etc, which seems to be in conflict with what we are trying to do here. I need to use the authenticated connection (which already works using the above code) when invoking lambda, so I cannot use generic invocation given in this example.
The Invoke API does not provide any examples as well.
Any advice is appreciated.
Note: if you do not need a response after your long running lambda, then consider API Gateways' Asynchronous Invocation
Amplify calls this approach "working with service objects".
To do this you'll have to ensure that the role Cognito gives your authenticated users includes permissions for lambda:invoke
as well as any additional permissions needed within the function. I'll assume you can do that for now, however you can see the Role-Based Access Control documentation, or ask another question if not.
To access these roles within Amplify you need to use the Auth.currentCredentials
function, which returns a promise with a credentials
object, which can then be used on an aws-sdk
client.
For example:
import Auth from '@aws-amplify/auth';
import Lambda from 'aws-sdk/clients/lambda'; // npm install aws-sdk
Auth.currentCredentials()
.then(credentials => {
const lambda = new Lambda({
credentials: Auth.essentialCredentials(credentials)
});
return lambda.invoke({
FunctionName: 'my-function',
Payload: JSON.stringify({ hello: world }),
});
})
You can see the full documentation for invoking lambdas on the AWS-SDK javascript documentation.
However you should be aware that the payload from API Gateway is constructed by AWS and includes much more information than just the body that the endpoint was called with, however when you invoke directly, all you'll get is the payload, so you'll have to build that payload object accordingly.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With