Closed ahmadizm closed 1 year ago
Pity there’s no news on this yet. I’m about to start a project and lack of JS support for resolvers is likely to make me move to another solution.
@markymc what other solution do you want to use? If you still stay with AWS and keep the app serverless, you'll need to use AWS Lambda with API Gateway. You can still use AWS Lambda with AppSync. With VTL, or these potential JavaScript resolvers, you can have lower latency and probably a bit less moving parts, but they are slightly harder to test.
I am looking forward to new JavaScript resolvers, too. But I am just curious to learn what's your alternative? Mostly because of the AppSync book we are working on.
@stojanovic might be worth checking out https://www.npmjs.com/package/appsync-template-tester if you haven't already
@alan-cooney Interesting, thanks. I use the AppSync Simulator package from AWS Amplify, it seems that it has more utilities, but some are still not implemented. It's good enough for most of the unit tests we have.
We'll probably publish the testing chapter of our book as an article soon, as that's one of the biggest pain points for AppSync.
There's also an excellent website to help you render to try rendering templates with different arguments: https://www.graphboss.com.
Ah super interesting thanks - I'll give it a try
@markymc what other solution do you want to use? If you still stay with AWS and keep the app serverless, you'll need to use AWS Lambda with API Gateway. You can still use AWS Lambda with AppSync. With VTL, or these potential JavaScript resolvers, you can have lower latency and probably a bit less moving parts, but they are slightly harder to test.
I am looking forward to new JavaScript resolvers, too. But I am just curious to learn what's your alternative? Mostly because of the AppSync book we are working on.
@stojanovic Good question. I'm considering a few options for my GQL backend (to work with my react-native-web JS frontend, I'm pretty experienced with GQL in general, so I don't need to learn about that), including:
I had a look at the TOC for your book... looks like exactly what I need!!! I don't suppose you need a test user in the near future? I'd be happy to provide feedback!
@markymc yes, these options seem reasonable. However, from my experience so far, most of them are more complicated and expensive than learning a few VTL tricks or writing direct Lambda integrations for the AppSync back end.
We run our product 100% on serverless using AppSync, and so far, three full stack developers can accomplish a lot with a low infrastructure cost(less than 1% of our MRR for all environments). VTL seems tricky, but in the end, it simply transforms text (a template) to text (a result JSON). With a decent unit test coverage, it's not magic anymore. JavaScript resolvers without testing utilities would be equally or more problematic.
If you have any questions, I am happy to try to answer them. This GH issue is not the right place for that, but feel free to ping me on twitter or via email.
P.S. A few more reviewers are always welcome for our book :)
👍 for ULID support in utils
feature request: Include SHA-1 in the $util package
Please Cloud Jesus, let this feature be delivered as soon as possible 👏 😆
Joking aside this would be amazing, the resistance towards VTL that many people have is a problem.
When can we expect this functionality in preview?
Amazed this is still open after a year, and with hundreds of customer reactions.
The management of this service needs improvement.
The AppSync engineers are passionate about the product and very opinionated, but sometimes their management team fails to recognize when it’s the right time to deliver impactful features for customers. Sometimes when critical issues like this are pending, AppSync management will choose to prioritize lower value tasks, which results in conflicts with customers, who are left frustrated with this product.
@jamesonwilliams I want this feature too, but I disagree that it is something with high priority.
You can always point your resolver(s) to lambda and use JS, TS and many others. Yes it will be cost you a little bit more, but it is possible to achieve.
We are using single lambda for all resolvers, so it stays hot most of the time.
👍 for ULID support in utils
We have just added a new VTL utility for generating a new ULID:
$util.autoUlid() : String Returns a 128-bit randomly generated ULID (Universally Unique Lexicographically Sortable Identifier). Doc: https://docs.aws.amazon.com/appsync/latest/devguide/resolver-util-reference.html
@ndejaco2 thanks is KSUID an option in the future?
Currently there is no KSUID utility but we will also put that in the backlog!
Hi all, I built a solution to this problem that allows you to build Appsync Resolver Pipelines with native TypeScript.
Take a look: https://github.com/sam-goodwin/functionless
Hi, we have launched the KSUID utility today: https://aws.amazon.com/about-aws/whats-new/2022/05/aws-appsync-simplifies-graphql-api-development-graphql-utility-helper-library/
@ndejaco2 Thanks the AppSync team for making this happen. Albeit you left us no choice but to climb the learning curve of Velocity, we still want this feature for the sake of simplicity in our tech stacks. This really aids recruitment and team management in the long run.
Even more excited about the new logging functionality - that solves a huge pain point in developing VTL templates. Thanks!
@atomos you can test with Jest ( and others I suppose ) with the amplify-appsync-simulator package.
A simple test looks like
const when = require('../steps/when')
const path = require('path')
const mappingTemplate = 'Guest.user'
const requestTemplatePath = path.resolve(__dirname, `../../mapping-templates/${mappingTemplate}.request.vtl`)
describe(`[RESOLVER] > ${mappingTemplate} template`, () => {
it('[REQUEST]', () => {
const context = {
source: {
userId: 'userId'
}
}
const response = when.we_invoke_an_appsync_template(requestTemplatePath, context)
expect(response.result).toEqual({
version: '2018-05-29',
operation: 'GetItem',
key: {
PK: { S: 'USER#userId' },
SK: { S: 'USER#userId' }
},
consistentRead: true
})
})
// [RESPONSE] => prevResult.response.vtl
})
Very much looking forward to this! I (and I'm sure many others) find VTL lacking a bit in terms of developer experience esp when writing templates in VsCode.
@RawadHaber
Check out: https://functionless.org/docs/concepts/appsync/usage
@ndejaco2 Thanks the AppSync team for making this happen. Albeit you left us no choice but to climb the learning curve of Velocity, we still want this feature for the sake of simplicity in our tech stacks. This really aids recruitment and team management in the long run.
Absolutely! We certainly understand the high learning curve of Velocity. While we continue to release utils like this to make it easier to use Velocity, we are simultaneously working on providing mechanisms to enable you to use JavaScript instead of Velocity for your resolvers.
@ndejaco2 Do you have time estimate for this?
Absolutely! We certainly understand the high learning curve of Velocity. While we continue to release utils like this to make it easier to use Velocity, we are simultaneously working on providing mechanisms to enable you to use JavaScript instead of Velocity for your resolvers.
@ndejaco2 Do you have time estimation for this?
Probably 1 month up to 5 years from now
Absolutely! We certainly understand the high learning curve of Velocity. While we continue to release utils like this to make it easier to use Velocity, we are simultaneously working on providing mechanisms to enable you to use JavaScript instead of Velocity for your resolvers.
@ndejaco2 Do you have time estimation for this?
Probably 1 month up to 5 years from now
But look on a bright side. By then, you'll master VTL (a limited though) and maybe even make good money as an AppSync consultant :smile:
@ahmadizm Hi, this is really great. Is there a timeline to releasing this feature?
I just spent two days fixing a VTL template. It turns out that if you \" in a variable and you then try to use that variable the whole thing goes kaboom.
That little detail plus the fact that when invoking Step Functions using a HTTP datasource, the request mapping template needs the input parameter in one line made me lose a chunk of my life. I ended up having to handle all possible cases of my input in a massive if-else-if-else block. If you wanna try this out try invoking Step Functions with App Sync and send it a big input that deserves several lines of code. If you wanna spice things up try to make the contents of that input dynamic and you'll see what I mean 🤯
I understand that VTL is performant but the complications it brings don't make sense.
For those advocating for the Lambda integration: the goal is Lambdalessness for the sake of "many things" plus performance which is key for web application APIs (probably the main use case for AppSync).
A very thin Javascript environment to run resolvers would be perfect. Kind of what CloudFront did with CloudFront functions. That runtime doesn't have a lot available but is blazing fast.
@cespin i also agree, a good sample of a thin js env is their cloudfront function ide. I found it much easier to apply a few limitations to a know coding env
Based upon feedback to this RFC and prototypes built to evaluate different potential ways to provide the ability to use JavaScript instead of VTL to implement resolver business logic, we have refined our approach and are now evaluating supporting JavaScript and Typescript in the AppSync service. We aim to make coding resolvers less error-prone, and more accessible to all developers.
The feature will allow developers to define their AppSync Resolver and AppSync Functions using a request function, and a response function. Each function would take a context object as an argument, and return a JSON value. For the request, the function returns the JSON object that AppSync uses to construct a data source request. For the response, the function returns the JSON object that returns data for the resolved field. Developers will be able to save their JavaScript or Typescript code directly to AppSync. If saving the resolver is not successful and configuration fails, a detailed error message will be returned in real-time.
Consider this sample code for a DynamoDB resolver as an example:
// file:resolver.ts
import { Context, $util, DynamoDBQuery, DynamoDBQueryResult } from '@aws-appsync/types'
export function request(ctx: Context) {
const { username: owner, claims } = ctx.identity
const { username, blogId } = ctx.arguments
console.log(`received request for ${owner}`)
if (username !== owner) {
console.error(`un-allowed operation with ${username}`)
$util.unauthorized()
}
const query: DynamoDBQuery = {
version: '2017-02-28',
operation: 'Query',
query: {
expression: '#k = :k and begins_with(#s, :s)',
expressionNames: { '#k': 'id', '#s': 'blogId' },
expressionValues: $util.dynamodb.toMapValues({ ':k': owner, ':s': `${blogId}#` }),
},
}
return query
}
export function response(ctx: Context) {
const now = $util.time.nowISO8601()
const result = ctx.result as DynamoDBQueryResult<Post>
let items = result.items.filter((item) => item.comments > 50)
console.log(`retrieved ${items.length} popular posts from ${ctx.arguments.blogId}`)
items = items.map((item) => {
item.fetchedOn = now
return item
})
return {
items,
nextToken: result.nextToken,
}
}
You would then be able to define your resolver with the AWS CLI as follows:
$ aws appsync create-resolver --api-id <id> \
--type-name "Query" --field-name "listPosts" \
--data-source-name "postTable"
--code file://resolver.ts
You may want make use of utilities in your code. It will be possible to write and re-use functions, and import local code. From the example above, you can refactor the code to extract the ownership check to it’s own utility file called local.ts
// file: local.ts
import { $util } from '@aw-appsync/types'
export function checkOwner(owner: string, username: string) {
if (!owner || username !== owner) {
console.error(`un-allowed operation with ${username}`)
$util.unauthorized()
}
}
You could then import the file in your resolver.ts file:
// file:resolver.ts
import { Context, $util, DynamoDBQuery, DynamoDBQueryResult } from '@aws-appsync/types'
import { checkOwner } from './local.ts'
import { queryBuilder } from './another-library.ts' // some other library
export function request(ctx: Context) {
const { username: owner, claims } = ctx.identity
const { username, blogId } = ctx.arguments
console.log(`received request for ${owner}`)
checkOwner(owner, username)
const query: DynamoDBQuery = queryBuilder({ owner, blogId})
return query
}
After bundling the files with esbuild:
$ esbuild resolver.ts --bundle --outfile=out.ts --format=esm --external:'@aws-appsync*'
You can create or update your resolver in the same way
$ aws appsync update-resolver --api-id <id> \
--type-name "Query" --field-name "listPosts" \
--data-source-name "postTable"
--code file://out.ts
When working with pipeline resolvers, you can write your AppSync function resolver code in the same way, and define your functions via the CLI or using your favorite IaC tool. For resolvers in pipeline configuration, the request function corresponds to the before mapping template and the response function corresponds to the after mapping template.
$aws appsync create-function --api-id <id> \
--name "function1" --data-source-name "postTable"
--function-version "2018-05-29"
--code file://fn1.ts
$ aws appsync update-resolver --api-id <id> \
--type-name "Query" --field-name "listPosts" \
--pipeline-config functions=function1-id \
--code file://out.ts
You would be able to write your resolvers in either VTL or Javascript/Typescript in your API. We are evaluating giving you the option to convert your JavaScript code back to the equivalent VTL code.
All of AppSync’s existing functionality will be available in JavaScript. You will be able to leverage AppSync’s $util
and $extension
utilities. To support developers coding in IDEs such as VS Code, we are evaluating providing definition files for AppSync’s utilities (e.g: @aws-appsync/types in the example above) that will make it easier to use them. This will provide documentation and auto-completion features from within your code. The tooling will also catch use of any unsupported or or unknown AppSync utility or extension, thus helping you avoid issues when your code is evaluated.
We are evaluating support of a subset of ECMAScript 6, and the majority of methods on primitive types and built-in objects (e.g.: string, numbers, object, and arrays). For example, we are evaluating support of most control flow structures (for-loops, conditional, switch statements, etc...), but may not support constructs such as while-loops or promises (because async use cases are not considered), and nested functions. To make it easy to catch these unsupported features in your code we are evaluating providing an eslint plugin (e.g.: eslint-plugin-appsync) and a set of recommended rules that will warn you of unsupported functionality in your code and provide guidance on alternatives if they exist. These rules will be included into the service and local tooling rules.
We are evaluating providing a test API that you will be able to use to validate and test your JavaScript resolvers. This will allow you to test your code against an environment that replicates AppSync’s behavior and evaluation. The API could be built to work similarly to the EvaluateMappingTemplate API for AppSync (more info on it in this blog post).
Consider the following command:
$ aws appsync evaluate-mapping-template --code file//out.ts --context "{}" --function request
A valid execution with logs could look like this.
{
"logs": [
"javascript:3:13 - a log line",
"javascript:6:18 - another log line"
],
"evaluationResult": "{\n \"version\": \"2017-02-28\" ..."
}
As highlighted in the blog post referenced above, you would then be able to incorporate this test API in your favorite testing framework like Jest or Mocha.
Syntax errors caused by language lines of code will be surfaced in logs, while contract errors during evaluation with AppSync's runtime interacting with a Data Source will have a custom format. This structure is still to be determined and will be presented at a later time.
While the solution will support imports, this functionality may be limited to local imports to begin with. Note that some existing limitations may still apply (e.g.: quotas). For instance, limitations would still apply to certain JavaScript operations which cannot run unbounded. For instance array.forEach
would be bounded.
Please comment on this thread if you have some thoughts or suggestions on this feature. Let us know if there is any functionality that you think is missing or if the approach is not addressing your development needs.
@onlybakam When is the new API going to be available?
@onlybakam thanks for the update. I have a few questions:
Will this work with CloudFormation? I understand that it's easier to show (and probably implement) this with the AWS CLI, but many people use IaaC tools such as CloudFormation for their applications. It's very hard to manage any system with more than five components with AWS CLI.
What are the benefits of transpilation? I know that implementing a new templating language is hard, but adding another layer to an already complicated system will not make it easier. There are now multiple things that can go wrong, such as:
While I definitely prefer writing JavaScript and TypeScript, I don't see this solution as "less error-prone, and more accessible to all developers." It is already hard to deal with VTL resolvers that are a bit more complex, I do not see that this will help in large production applications, but I might be wrong, of course.
If this implementation is a transpiler, why would you hide it behind the AWS CLI? I think it would make much more sense to publish it as an open-source library. There should be no hidden business logic in the transpiler, and open sourcing it would make the development experience much faster and more pleasant.
You mentioned that the error while saving the resolver would result in "a detailed error message (that) will be returned in real-time." However, I don't see how that will work in real-time with the CloudFormation deployment, especially if the AppSync is in a nested stack. By open sourcing this tool, we would at least be able to use it to transpile (and maybe test) our templates in the build phase before we start the deployment process.
cc @awsed
hey @stojanovic , for 1: for brevity i showed CLI examples but could have been cloudformation or CDK. the goal is for this to work with cloudformation (AppSync supports cloudformation for its resources like resolvers); which is really important for developers.
for 2, and 3: we are still investigating details, and we havent settled on a mechanism or approach. The error message we are returning has to do with configuration. if the function definition you provide is not "correct" (still to be defined), we would provide an error message explaining the reason. The behavior would be the same with the CLI or cloudformation.
~At runtime is it running under a JS runtime? Or is it getting compiled directly into the underlying VTL? I assume the former as I imagine there are things in JS you cannot do in VTL. Unless it just errors in those cases~
Read closer and I see you have the eslint plugin to disallow things not supported so it seems like it's transpiling to VTL?
we're still evaluating this, but because we may not be able to support all javascript features, we think an eslint plugin will be a good way of providing guidance when coding. idea is to avoid using unsupported features. Along with the type definition and auto-completion, this could be a good way of doing this.
Thanks @onlybakam for being transparent about the thought process!
Developer tools such as @aws-appsync/types
and the new eslint
rules are absolutely needed, this really aids development and improves DX!
If a new JavaScript runtime is not happening within AppSync, then I am with the previous comments. An open-source transpiler would be a much better way for debugging.
This works great in tandem with testings.
Instead of a JavaScript/TypeScript validator, I would rather suggest a VTL renderer instead. It can either lives inside AppSync as a hosted API method, or an offline renderer. It should renders the template outputs from a user specified input event object.
We currently deployed large VTL templates to translate an array of GraphQL inputs into OpenSearch queries, if such a VTL renderer is available, it opens up the possibilities of unit testing, which is not possible at the moment until e2e phase.
Because of the delayed nature when updating AppSync VTL templates, debugging is quite a pain because we have to repeatedly query a dev endpoint until we see an updated response.
Any word on a 100% code first approach? VTL is an actual blocker for us to adopt AppSync - nobody uses it enough to be an expert and AppSync has massive limitations for us without a code first approach, especially with resolvers, but it would be great to get out of these configuration languages like YAML and VTL and be able to do everything via JavaScript.
Not to mention proper unit testing is nearly impossible.
@onlybakam . Thanks for the update.
If I understood it correctly, we are just creating an another layer for resolvers in which we can write code in JS / TS instead of VTL , but it would still have the same limitations of VTL.
For example: When I thought of JS resolvers, I thought we would now be able to make multiple DB calls in the same request resolver ( because we would be using JS right ? ) , but to me it appears that it can't be done under JS too , unless you use the pipeline resolvers or Lambda resolvers.
I get a feeling that Appsync would just translate your JS code into VTL templates under the hood . As a developer, I feel that I would still be limited in fully utilising the language we use to code everyday. We would still be limited to understand what's allowed in JS resolvers and what's not.
The tiny JS rules & runtimes makes sense on the least used features such as in Cloudfront functions , but in case of API, which are being developed or refactored on daily basis, having a pre-defined limitations on how to write JS resolvers doesn't make sense. To me it still looks prone to errors.
I also thought that the new JS resolvers would allow us to migrate some lambda resolvers ( a simple one, but not complex ) into JS resolvers, but I don't think that would be achievable with the new flow you presented.
Any thoughts ? I may be wrong as well in my understanding. Please correct me , If I understood it incorrectly.
Even under this feature's most ambitious proposal you were never going to be able to make multiple database calls in a resolver because it doesn't fit into AppSync's architectural model. You will still need to render a request descriptor which is then passed onto the opaque DynamoDB database layer or the next resolver in the pipeline.
No doubt there's going to be a lot of unhappy campers with this implementation. For our team we had this fantasy that we would be able to use our GraphQL service to pre-sign S3 PutObject requests in order to replace Amplify's, quite frankly insane and insecure, storage
feature. But there's not a chance that even 1 in 100 npm packages will run under this translation layer, so that is out of the question.
Even a seemingly reasonable goal of replacing the default multi-kilobyte pagination tokens with, say, an item's timestamp attribute is also impossible under this model.
The transpilation approach is an impressive engineering feat and probably the best the team can do given the circumstances. I fear that AppSync is just fundamentally flawed and without a radical redesign customers are going to continue feeling constrained.
I for one am very excited about this, and transpilation sounds like a totally reasonable approach to me. It accomplishes the main problems I have with VTL:
(1) eslint compatibility! This is my main pain point with VTL. Errors flagged in a code editor or at upload time (especially "any unsupported or or unknown AppSync utility or extension") will save a lot of trial and error testing.
(2) Code reusability is music to my ears!
(3) Javascript is more readable and much more widely understood than VTL.
(4) A testing API is good, but a localized test environment would be better. I'd prefer not to have my automated test suite dependent on a remote AWS API.
100% JS compatibility and support for multiple DB calls are understandably outside the scope of this simple translation layer. For that, we have lambda. I do agree with @laverdet that S3 integration is a huge missing link - IMO even more important than javascript support - but that's a separate issue. There's a GitHub issue tracking that request here.
The transpilation approach is an impressive engineering feat and probably the best the team can do given the circumstances. I fear that AppSync is just fundamentally flawed and without a radical redesign customers are going to continue feeling constrained.
It sounds like you want to run any code at all, including modules etc... so itsn't that the same as using the current lambda resolver (I feel like I'm missing something) ?
My take on this is about the responsibility model - here AWS is saying they support VTL (all security / patching / performance improvments etc are their problem). If this got opened to run anything then us as the customers have to take on a lot of that responsibility and frankly that's something to be avoided IMHO.
The approch they seem to be taking to my mind is best of both, I can write in TypeSciprt but AWS takes the responsility of managing the compile (to VTL) and run time (AppSync).
I would love a TS->VTL open source utility so I could run this locally for testing and the like but beyond that I don't want to take on more responsibility if possible.
I'm surprised to hear AWS's plan is to transpile TS to VTL. We already implemented that in functionless https://github.com/functionless/functionless and would be more than happy to separate it out into a standalone library and collaborate with aws. The last thing we need is another purely server side solution that can't be improved by the community (looking at you CloudFormation and step functions).
A better solution would be network constrained NodeJS isolates. Has the aws team explored that option?
We already implemented that in functionless https://github.com/functionless/functionless and would be more than happy to separate it out into a standalone library and collaborate with aws.
@sam-goodwin I'll be there for https://github.com/functionless/functionless/issues/257
A better solution would be network constrained NodeJS isolates. Has the aws team explored that option?
I feel like this would indeed be better because then one isn't constraint by which JS syntax can or cannot be compiled to VTL. A runtime similar to the one for CloudFront Functions could open up a lot more possibilities.
@vicary can you provide a bit more information about the renderer idea?
Regarding Lambda, as we pointed out initially:
It’s not possible to import external Node.js modules in order to maintain a lean and optimized AppSync runtime layer specifically for GraphQL workloads. If developers want to import modules or do anything more complex, the recommended approach is to use Direct Lambda Resolvers.
While we aim to make writing resolvers easy with typescript/javascript support, for complex scenarios Direct Lambda Resolvers (using AWS Lambda functions) is still the recommended approach.
@vicary can you provide a bit more information about the renderer idea?
@onlybakam I was incorrect about it. The renderer idea is already available via AppSync#evaluateMappingTemplate.
The issue is that we specifically matches our aws-sdk
version with the current Lambda runtime to reduce bundle size. It also prevents our team from using methods which is not yet available. The method evaluateMappingTemplate
is such an example in the current Node.js runtime aws-sdk@2.1055.0
.
It's a mild inconvenience, but I believe we can work with it. Thanks for the heads up!
GraphQL has a built-in compute or runtime component where developers can customize their own business logic directly at the API layer. These components are called Resolvers, and they provide the logical glue between the data defined in the GraphQL schema and the data in the actual data sources. Using resolvers you can map an operation or even a single field of a type defined in the schema with a specific data source, which allows to retrieve data for different fields in different data sources with a single API call. They are called “Resolvers” because they are built-in functions in GraphQL that “resolve” types or fields defined in the GraphQL schema with the data in the data sources.
AppSync currently leverages VTL or Apache Velocity Templates to provide a lean and fast compute runtime layer to resolve GraphQL queries or fields. It uses VTL internally to translate GraphQL requests from clients into a request to a data source as well as translate back the response from the data source to clients.
However, if you’re not familiar with VTL you need to learn a new language to take full advantage of these benefits, which can potentially delay the implementation of a GraphQL project for your business. While there are toolchains such as the Amplify CLI (https://docs.amplify.aws/cli/) and the GraphQL Transformer (https://docs.amplify.aws/cli/graphql-transformer/overview) that can automatically generate VTL for AppSync APIs, customers have told us that sometimes they just want to write their own resolver logic in a language they are familiar with and the preferred runtime to do so is JavaScript.
As an alternative to VTL, we're evaluating adding support for JavaScript as a runtime for AppSync resolvers. Developers will be able to leverage all native JavaScript constructs (i.e. switches, maps, global libraries such as JSON and Math, etc) in a familiar programming model based on the latest ECMAScript specification. Ideal for simple to complex business logic where no external modules are required. Just like VTL all JavaScript Resolvers code is hosted, executed and managed internally by AppSync. Customers don’t have to manage their GraphQL API resolvers business logic in other AWS services.
We propose JavaScript Resolvers are stateless and don’t have direct internet/network access to data sources, network access is handled by the AppSync service. For instance, in order to access an external API the resolver needs to be setup as an HTTP Resolver with JavaScript. AppSync executes the business logic defined in the resolver then sends the transformed request to the data source and the data source only (DB or external API). There's no access to the local file system where the Resolver is executed either. Global objects such as JSON and Math are pre-loaded and available, async/await is supported however window() and API's such as fetch and XMLHttpRequest are not.
All the utilities currently provided by VTL ($util - https://docs.aws.amazon.com/appsync/latest/devguide/resolver-util-reference.html) will be available for JavaScript Resolvers unless there’s a related utility already available natively on JavaScript (i.e. JSON.stringify, JSON.parse). Just like JSON and Math, “util” is also a global object built-in to the resolvers and automatically available. Similar to VTL, all data sources information, including connection strings, endpoints, tables and permissions, are all baked into the resolver and managed by AppSync to securely connect to the data sources.
It’s not possible to import external Node.js modules in order to maintain a lean and optimized AppSync runtime layer specifically for GraphQL workloads. If developers want to import modules or do anything more complex, the recommended approach is to use Direct Lambda Resolvers.
Please comment on this thread if you have some thoughts or suggestions on this feature or if you think we’re missing any story points which you would love to see as a part of this feature.
Sample None Resolver:
Sample DynamoDB Resolver: