Graphql query resolvers split into seperate lamdas - aws-lambda

I am writing a serverless app using aws lambdas. we are using apollo graphql for single endpoint. graphql endpoint run in one single lamda, how can i split graphql query mutation resolvers into seperate lamda functions, like in graphcool and aws app-sync.

AWS AppSync has the concept of Datasources which can be individual Lambda functions (or you can use DynamoDB tables or Elasticsearch domains). In your GraphQL schema you would then attach a resolver to a field (like a query or mutation) and this resolver would invoke the Lambda datasource. AppSync lets you do this as a single Lambda invocation or "BatchInvoke" for having the Lambda hit multiple resources and return a LIST.
The resolver template (written in Velocity Template Language) is fairly straightforward to send your GraphQL request on through to Lambda, and adding this is a drop down selection from the samples in the console:
{
"version" : "2017-02-28",
"operation": "Invoke",
"payload": $util.toJson($context.arguments)
}
You can read more about this here: https://docs.aws.amazon.com/appsync/latest/devguide/tutorial-lambda-resolvers.html

As of now, the only way to do it on Apollo is to call your Lambdas by their URIs. The good about this is that you can cache their responses. The bad part is that you can't have a pure GraphQL environment.

Related

Using dynamodb document client on step function workflow

Am trying to get results for a getItem action as "normal" json instead of the DynamoDB json format on my step function workflow.
If i use:
"Resource": "arn:aws:states:::dynamodb:getItem"
On my ASL file i get the DynamoDB json format, for example:
{
"entity_id": {
"S": "d0e96ad0-4f83-4aa7-bcaf-2cf02c6216cb"
}
}
And i need:
{
"entity_id": "d0e96ad0-4f83-4aa7-bcaf-2cf02c6216cb"
}
I could create lambdas to interact with dynamo and use de sdk documentClient but it will be really convenient to be able to do that directly with the ASL template.
So far i tried something like:
"Resource": "arn:aws:states:::aws-sdk:dynamodb:documentClient:getItem"
But is not valid for the template. Also did a bit of research into intrinsic functions with no success, i could also do some mapping and use ResultSelector but at that point i guess is better to use a lambda
Stepfunctions uses Java SDK V2 to interact with DynamoDB and unfortunately can only return DynamoDB JSON. You would need to use a utility function on the client side to parse the DDB JSON or as you mentioned use a document client in Lambda.

Authorize based on field value in another document in AppSync GraphQL custom authentication via Lambda Resolver

I am new to Amplify Datastore & AppSync w/ GraphQL, but in Firestore, you can write an auth rule like: allow delete: if request.auth != null && get(/databases/$(database)/documents/users/$(request.auth.uid)).data.admin == true [https://firebase.google.com/docs/firestore/security/rules-conditions#access_other_documents] -> which would grab the document at /users/{id}/ and I can access the admin field to write a security rule logic.
How do you do the same in a Lambda function resolver?
I am aware that the solution may involve a Lambda resolver (https://stackoverflow.com/a/68581796/9824103) but I cannot find any reference to reading a specific document and doing logic to authorize or deny an operation based on a field value in a document. I am only asking how to do this specific thing. Thank you!
I followed https://docs.amplify.aws/cli/graphql/authorization-rules/#custom-authorization-rule to create a custom authorization rule via adding the #rule directive: type MyModel #model #auth(rules: [{ allow: custom }]) and.. although the lambda function isn't really getting called when I try to write a listMyModel or createMyModel (any hints as to why that would be great), I am focused on writing the lambda function to read query a document and check a certain field to meet my custom auth condition.
fyi, I am using Flutter based amplify-cli.

How to create a custom, hardcoded health check GraphQL query with AWS Appsync?

I'm new to AWS Appsync and to GraphQL.
Previously, I used to create REST APIs in Python. I was always creating a GET /health-check endpoint, sending back, for example and among many other info, the API version number, easily parsed from the project descriptor pyproject.toml file.
That helped me massively to maintain APIs: with a single GET query in my browser, I was always able to instantly get if branch/version it was, the status of other services, etc. .
I want to do something similar with AWS Appsync / GraphQL and my IaC tool (Pulumi).
Since I'm using IaC tool Pulumi in Python, I could still easily get the info I need and inject them in any resolver response template.
But if I create a resolver, should I create a corresponding health-check query itself in the GraphQL schema? When creating a resolver with a hardcoded JSON response, should it be associated with a GraphQL query in the schema, and if yes, how should that query in the schema look like?
I finally found a way, but it's a very ugly workaround since AppSync VTL resolvers have a lot of limitations and since I'm using Pulumi as a Iac tool which also doesn't accept all arguments when creating a resolver - for example for GetItem operation it needs an id key in the request template.
I'm posting the workaround here anyway if it can be of any help to someone.
GraphQL schema:
schema {
query: Query
}
type Query {
getHealthCheck: String
}
AppSync getHealthCheck resolver request template:
{
"version": "2018-05-29",
"operation": "GetItem",
"key": {
"id": $util.dynamodb.toDynamoDBJson(""),
},
}
AppSync getHealthCheck resolver response template example:
"'version':'0.1', 'branch':'staging', 'commitId':'abc123'"
So in a IaC tool like Pulumi using Python, one could build the response template like that:
"""
"'version':'{}', 'branch':'{}', 'commitId':'{}'"
""".format(
version,
os.environ.get("GITHUB_REF_NAME", "unknown"),
os.environ.get("GITHUB_SHA", "unknown"),
),

How to get the current user from a Lambda resolver in AWS Amplify (GraphQL api and NodeJS Lambda)?

I have a graphql Api and added a lambda function to resolve a mutation.
type Mutation {
addTeamMember(email: String!, teamId:ID!): String #function(name: "add-team-member-${env}")
}
From the lambda I want to retrieve the authenticated user that sent the request to perform additional validations, ¿How to retrieve it from the request information?
strong text
I printed the contents of the first lambda parameter and found it:
Access it with:
event.identity.username

aws amplify graphql computed field inline resolver

For complex field resolver, I know #function directive is the way to go.
But how about those very simple computed fields. #function directive with lambda is a little too much. I see prisma has inline javascript function supported. see the answer of similar quest.
Not sure whether aws-amplify graphql support inline function.
You can override the default VTL resolver for the field, just adding the logic you want.
This article goes into detail on a simple use case (similar to yours I think)
Just a few steps
Add the field to your schema
Build your API
Look for the auto-generated resolver (amplify/backend/api/client/build/resolvers) The naming convention is straight-forward.
Copy it to amplify/backend/api/client/resolvers
Change it as needed
Push your changes to Amplify
In the article he has just added a new set item
## [Start] Prepare DynamoDB PutItem Request. **
$util.qr($context.args.input.put("createdAt", $util.time.nowISO8601()))
$util.qr($context.args.input.put("updatedAt", $util.time.nowISO8601()))
# The next line was added
$util.qr($context.args.input.put("active", false))
AWS has some tutorials over VTL that you might want to take a look.
And Amplify has more docs on custom resolvers using VTL

Resources