Lambda functions to query the GraphQL endpoint? - node.js

How can I use Lambda functions to query the GraphQL endpoint (AppSync) in Node.js? Which GraphQL Client should I use?
I have seen AWS AppSync JavaScript SDK which seems to be for mobile app or react/frontend.
PS: I am not talking about AWS Lambda Resolvers.

We use a simple https package to query graphql. You might need to form all the graphql queries manually in that case. If you want to use deal with automated discovery and query with objects you can apollo-fetch clients. Simple CURL works too.
All of the methods are mentioned in detail here.
https://blog.apollographql.com/4-simple-ways-to-call-a-graphql-api-a6807bcdb355
Hope it helps.

If you use AWS_IAM or AMAZON_COGNITO_USER_POOLS as the authentication type, I think AWS AppSync JavaScript SDK is a big help, you just need to set up your code as explained here:
"use strict";
/**
* This shows how to use standard Apollo client on Node.js
*/
global.WebSocket = require('ws');
require('es6-promise').polyfill();
require('isomorphic-fetch');
// Require exports file with endpoint and auth info
const aws_exports = require('./aws-exports').default;
// Require AppSync module
const AUTH_TYPE = require('aws-appsync/lib/link/auth-link').AUTH_TYPE;
const AWSAppSyncClient = require('aws-appsync').default;
...
Also, you must provide credentials
const AWS = require('aws-sdk');
AWS.config.update({
region: aws_exports.REGION,
credentials: new AWS.Credentials({
accessKeyId: aws_exports.AWS_ACCESS_KEY_ID,
secretAccessKey: aws_exports.AWS_SECRET_ACCESS_KEY
})
});
const credentials = AWS.config.credentials;
or just retrieve Lambda session credentials (don't forget to give permission to Lambda execute GraphQL API).

Related

AWS S3Client throws error: 'emitWarning' is not a function

I am trying to create an S3Client using the #aws-sdk/client-s3 package, as shown below:
const { S3Client } = require('#aws-sdk/client-s3')
const client = new S3Client({ region: 'us-east-1' })
It runs fine locally, but when I upload the code to a MongoDB Realm function along with the client-s3 dependency, it throws the error: {"message":"'emitWarning' is not a function","name":"TypeError"}
What might be causing this error?
It turns out this was happening because the MongoDB Realm Functions environment does not have an emitWarning function defined on the global process variable, which is why the error kept saying 'emitWarning' is not a function.
I reached out to MongoDB Support about this, and apparently the AWS-SDK v3 just isn't compatible with MongoDB Realm Functions.
Instead, you must use the AWS-SDK v2. I eventually found this MongoDB Forums Article, which explained that they specifically support v2.737.0 of the SDK.

Failed attempts to write to DynamoDB Local

I recently discovered DynamoDB Local and started building it into my project for local development. I decided to go the docker image route (as opposed to the downloadable .jar file.
That being said I've gotten image up and running and have created a table and can successfully interact with the docker container via the aws cli. aws dynamodb list-tables --endpoint-url http://localhost:8042 successfully returns the table I created previously.
However, when I run my lambda function and set my aws config like so.
const axios = require('axios')
const cheerio = require('cheerio')
const randstring = require('randomstring')
const aws = require('aws-sdk')
const dynamodb = new aws.DynamoDB.DocumentClient()
exports.lambdaHandler = async (event, context) => {
let isLocal = process.env.AWS_SAM_LOCAL
if (isLocal) {
aws.config.update({
endpoint: new aws.Endpoint("http://localhost:8042")
})
}
(which I have confirmed is getting set) it actually writes to the table (with the same name of the local dynamodb instance) in the live AWS Webservice as opposed to the local container and table.
It's also worth mentioning I'm unable to connect to the local instance of DynamoDB with the AWS NoSQL Workbench tool even though it's configured to point to http://localhost:8042 as well...
Am I missing something? Any help would be greatly appreciated. I can provide any more information if I haven't already done so as well :D
Thanks.
SDK configuration changes, such as region or endpoint, do not retroactively apply to existing clients (regular DynamoDB client or a document client).
So, change the configuration first and then create your client object. Or simply pass the configuration options into the client constructor.

Call a lambda from another Lambda all locally within Serverless

I am using serveless + aws + node.js.
I have a lambda calling another lambda. I can't get to run the lot locally.
I can invoke both lambdas locally with 'serverless invoke local -f ...' BUT
the caller one comes back with:
{"message":"Function not found: arn:aws:lambda:eu-west-1:5701xxxxxxxxxx:function:the-right-function-name"}
as if the caller function invoked the callee on AWS and not locally.
Is there anyway to do stay local and if yes, what may I be missing?
You can achieve that with this plugin. There is a feature of AWS SDK for Lambda that allows you to override the API endpoint of Lambda service. Therefore you can set it to localhost.
const AWS = require('aws-sdk');
const endpoint = process.env.SERVERLESS_SIMULATE ?
process.env.SERVERLESS_SIMULATE_LAMBDA_ENDPOINT :
undefined
const lambda = new AWS.Lambda({ endpoint })
For more details, refer to the plugin's readme. Also there is a nice article about that.

How to turn an AWS lambda function into an own https endpoint?

I implemented a lambda function on AWS to create an Alexa Skill. I would like to use a https endpoint on another server with node.js. I have no concept on how to approach such a port.
This is my example code of the aws lambda function:
const skillBuilder = Alexa.SkillBuilders.custom();
exports.handler = skillBuilder
.addRequestHandlers(
LaunchRequestHandler,
MyIntentHandler,
TestIntentHandler,
HelpIntentHandler,
CancelAndStopIntentHandler,
SessionEndedRequestHandler
)
.addErrorHandlers(ErrorHandler)
.lambda();
and as an example, one of the handlers:
const LaunchRequestHandler = {
canHandle(handlerInput) {
return handlerInput.requestEnvelope.request.type === 'LaunchRequest';
},
handle(handlerInput) {
const speechText = 'Hello';
return handlerInput.responseBuilder
.speak(speechText)
.reprompt(speechText)
.withSimpleCard('Welcome', speechText)
.getResponse();
},
};
I would need help regarding the node.js app and how to translate this lambda function. Thank you in advance
There are a few options, considering your response in the comments section:
1 - You can create an HTTPS endpoint in API Gateway. The endpoint will get the data received in the https call and forward to lambda, then it will wait the function execution and forward the response. You can find more information here (http://docs.aws.amazon.com/apigateway/latest/developerguide/);
2 - You can provide an https endpoint in a server that you control and can use the aws-sdk (Javascript, Java, Python, etc.) to make a call to lambda function. Like a http service running inside EC2. You can find more information here for node.js (https://docs.aws.amazon.com/sdk-for-javascript/v2/developer-guide/lambda-examples.html);
3 - Now you can make a call to an SQS queue and configure it to fire the lambda execution. The same solution is available using AWS Kinesis. The SQS Queue receive messages as https calls. But this solution probably will need a third party to send the response for the original caller. You can find more information about this option here (http://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/).
Ok, sorry about this extra answer, but when I remembered I could'n stop thinking about how fool I were. So....
All AWS services were designed to be used primary as an https endpoint. The AWS Console, the aws-cli and all AWS-SDK's are just proxies to https calls. Knowing this you can make a simple https post request to invoke the lambda function. The API documentation for this request is here (https://docs.aws.amazon.com/lambda/latest/dg/API_Invoke.html).
But it only appears simple... the post request to be made must be signed with your access and secret keys. If it it not signed, it will not be accepted by AWS. It's not a simple process (but you must implement it only a single time in a util function). The console, aws-cli and aws-sdk automatically sign the requests for you, so they must be your primary option.

AWS Cognito SDK Node.JS Implementation

I am working on a server for an API that I am developing that is being built using node.js and requires the use of AWS Cognito. Before this, we developed a working version of this application on client side that used the AWS SDK, and I am currently trying to translate that functionality over to the server side. I am struggling to find a good way of doing this and have a few specific questions that, if answered, would probably allow me to get the implementation I am looking for. Basically, I want to know what the AWSCognito object is and how to access it like I see in the following line of code.
var poolData = {
UserPoolId : 'us-east-###########',
ClientId : '########################'
};
var userPool = new AWSCognito.CognitoIdentityServiceProvider.CognitoUserPool(poolData);
Currently my code is set up using the complete AWS SDK, installed using [a] and accessed in my code using [b].
[a] npm install --save aws-sdk
[b] var AWS = require('aws-sdk');
Is there a way to access this AWSCognito object from my AWS object? If so, how do I do that? If not, how do I get access to it/is it even possible to access it?
Edit: In broad summary, I just want access to the following functions and have no clue how to access them from a node.js server-
userPool.signUp(username, password, attributes, callback)
cognitoUser.confirmPassword(verification, newPassword, {})
cognitoUser.forgotPassword({})
cognitoUser.authenticateUser(authenticationDetails, {})
userPool.getCurrentUser()
cognitoUser.getSession(callback)
cognitoUser.confirmRegistration(verification, bool, callback)
cognitoUser.updateAttributes(attributeList, callback)
cognitoUser.getUserAttributes(callback)
Edit: Update 1
The AWSCognito object is something being set to a global variable in the window by the AWS Cognito SDK. This is a process that only works client-side (yes I know there are hacky solutions to emulate a window on my server, I would prefer not to use these). Is there an equivalent object on server side that I can access and call functions from?
You can use Cognito in a Node.JS environment, but doing so with the AWS SDK for JavaScript is a bit different from doing so with the AWS Cognito SDK. Based on the names of the functions you want to access, you should take a look at the Cognito Identity Provider Service. Operations that start with admin are meant to be called from a server using AWS credentials.

Resources