Open rayhaanq opened 6 years ago
We don't package any transformers that allow you to do this out of the box but have discussed use cases like this in the past. If you want to do this purely using the schema.graphql
today, you can write your own transformer that will augment the generated resolver template code. To make this work you will also need to write your own light-weight CLI that loads and runs the transformer. There are docs on this here https://aws-amplify.github.io/docs/js/graphql#writing-custom-transformers.
The way to implement this in AppSync is to write resolver code that validates inputs during mutations. For example, if you wanted to validate that the "name" is a max of 250 characters then you would add a snippet like this to createPerson and updatePerson resolvers:
## mutation.create/updatePerson.request.vtl **
#if( $ctx.args.input.name.length() > 250 )
$util.error("Value for input field `CreatePersonInput.name` cannot exceed 250 characters.")
#end
If you provided a name longer than 250 characters this would cause the mutation to fail before saving the object to DynamoDB. This is how your custom transformer would work too, but you would be generating the above snippet in your transformer instead of writing it by hand.
What directives would you like access to? Over the long term, we can work on building a few transformers that tackle common issues but it would be helpful to hear more about the use cases you want to be solved.
For example, I would suspect these two would be useful:
@regex
directive @regex(expression: String!) on FIELD_DEFINITION
Usage
type Post {
id: ID!
title: String @regex(expression: ".*graphql.*")
}
@length
directive @length(min: Int, max: Int) on FIELD_DEFINITION
Usage
type Post {
id: ID!
title: String @length(min: 10, max: 255)
}
There are a lot of possibilities so let me know what you think and we will prioritize based on demand.
@mikeparisstuff thanks for the code snippet. I'll take a look at this. As for the possible directives. I guess what you mentioned sounds reasonable with the addition of maybe:
there's also a few common simplified regex checks I guess. @startsWIth, @endsWith, @contains
also for the length implementation, should max be optional somehow? Maybe we want the value to be at least 10.
@rayhaanq Thanks for those suggestions. I will take a note of all of these and will try to write up a more formal design that covers a subset of useful directives and publish it so that we can get more feedback on these features.
This is also another good use case for supporting custom transformers that would allow you to define your own directives that could be run as part of the Amplify CLI. For example, you could write a transformer on your local machine and then import it such that it is loaded by the amplify CLI:
"transformers": [
"path/to/local/transformer.js"
]
Would you be interested in such functionality? This would provide another safety hatch for advanced behavior that is not supported OOTB by the transform.
I would be interested for sure. I was looking for something like a @readonly directive which would cause the field to be excluded from the generated Inputs but available for "reading". I'd imagine a @writeonly field might be something we'd want as well. Maybe something like @toUpper @toLower, etc. It would be great to be able to create these on our own even if not available in core amplify-cli.
Do we have any update about those new directives? This is a very interesting matter if we want to build an complete application while writing the minimum of serveless code
This would be amazing! Hoping for news on availability soon... maybe re:Invent?!
This would be great and would really make writing complex models a breeze! Is there anything planned for above mentioned directives?
I would be interested for sure. I was looking for something like a @readonly directive which would cause the field to be excluded from the generated Inputs but available for "reading". I'd imagine a @writeonly field might be something we'd want as well. Maybe something like @toupper @tolower, etc. It would be great to be able to create these on our own even if not available in core amplify-cli.
I think the @readonly
usage is covered by: https://www.npmjs.com/package/graphql-auto-transformer by @hirochachacha
And there's @tolower
: https://www.npmjs.com/package/graphql-lowercase-transformer by @hisham
Hopefully someone can step in and create the directives mentioned by @mikeparisstuff above.
I've made https://github.com/hirochachacha/graphql-assert-transformer
type Post @model {
id: ID!
title: String @assert(condition: """.length() > 3 && .matches("t.*")""")
text: String @assert(condition: ".length() > 10")
episode: Int @assert(condition: ". % 2 == 0")
}
It would be great something like this to uniq validation or any other necessity:
@custom("lambda-${env}")
Any updates on the custom field validations?
Fro custom field level validations, I would highly recommend looking at writing custom transformer directive plugins based on our docs here - https://docs.amplify.aws/cli/plugins/authoring#custom-graphql-transformers
Found a similar 3rd party custom directive plugin here for field level validations/operations - https://www.npmjs.com/package/graphql-default-value-transformer and the code for which is here https://github.com/trek10inc/graphql-default-value-transformer
Also, as @andreialecu mentioned there are some more 3rd party custom directives which you could leverage:
@readonly usage is covered by: https://www.npmjs.com/package/graphql-auto-transformer by @hirochachacha @tolower: https://www.npmjs.com/package/graphql-lowercase-transformer by @hisham
If you'd like something really specific which can't be built with a custom directive and which all our customers can leverage as a default, I would recommend opening up an RFC in our repo and we can discuss it for including it as a part of our code offering.
any updates on this??
Any update on this? Is there any plan to integrate something like https://github.com/hirochachacha/graphql-assert-transformer within amplify? I suppose validation is quite a common use case for every one. I understand it is possible to write custom resolvers, but having the chance to declare it in the schema.graphql like shown in graphql-assert-transformer would be a great advantage I reckon.
+1
If I'm understanding correctly, there's no simple way to have a lambda function perform validation as part of an update action on a model, right?
I was hoping a directive like @function
on a model would allow me to check the data that's about to be applied in the update and reject it if it fails my validation - currently this is not the case, but I would like to see something similar to this. I feel like custom validation is essential but I'm not finding a straightforward way to accomplish it, any insight would be helpful. Thanks!
relevant in regards to constraints aws-amplify/amplify-category-api#286
If I'm understanding correctly, there's no simple way to have a lambda function perform validation as part of an update action on a model, right? ...
Maybe I missed this before or my use case was different, but I found that I can add a custom mutation
to my schema that points to a Lambda resolver to perform the operation. Here I was able to perform the necessary validation before the update was complete.
I followed this guide: https://www.theclouddeveloper.io/use-lambda-resolvers-in-your-graph-ql-api-with-aws-amplify
I guess this is what you do when you need something outside of the generated CRUD operations.
It has been 4 years. Nothing yet? 🥴
it's been 5 years and still nothing from the aws team. 😢
in the absence of any official movement, i've created a set of input validation directives for strings (String
) and numbers (Int
and Float
). however, it is currently blocked by #2077
~once~ if this gets resolved, then i will publish these to npm.
and if we do get there, i will expand the validators to date/time (AWSDate
, AWSTime
, AWSDateTime
), etc
we can only hope.
i have it working now - i will release to npm shortly.
Which Category is your question related to? Amplify GraphQL API
Is it possible to add validation to fields in the schema file? So min/max length, min/max value etc? If I had a field on a Person type and wanted to limit their name field to 250 characters, is that possible using the schema file only? Otherwise how can this be done?