In GraphQL Transform, transforming a schema that includes @key
directive like: @key(fields: ["id", "createdAt"])
forces to make key fields non-nullable and that results with mandatory id
and createdAt
fields in CreateItemInput
. Since CreateItemInput
has these mandatory fields, it is a must to pass id
and createdAt
to createItem
mutation. I want createdAt
to be handled by automatically like mentioned here if it is possible: Timestamps for GraphQL/AppSync models
Example:
type Item @model @key(fields: ["id", "createdAt"]){
id: ID!
createdAt: String!
}
Result:
input CreateItemInput {
id: ID!
createdAt: String!
}
Expected Result:
input CreateItemInput {
id: ID
createdAt: String
}
Also it is not limited to createdAt. Using @key
directive with custom fields like @key(fields: ["id", "sortKey"]
results with non-nullable id
and sortKey
fields in CreateItemInput
and UpdateItemInput
.
I am in favor of this. A scenario where this is critical is a real time application where the date field must be controlled by one global system/server that sets the time. If the time is set by the application code, then there could be lapses and inconsistencies reflected in time of multiple events. If device A creates a mutation before device B, there is a strong possibility device B's time record in the database is earlier than the record of device A (This is due to the system time of each device). This is a BIG problem if device A and B are communicating.
A solution in the mean time would be to send the records to a AWS lambda function to deal with the mutation, that is, the AWS lambda function handling the createdAt
time would be global for all devices. However, I have not thought much into this solution, still looking into way as this is a current problem I am facing.
I did some research and a quick solution would be is to use an api to get a uniform time. If it is very important for the time timestamp to be consistent (which it should) you can use truetime
library. I am using the truetime
library so regardless of any system my application is running on, I will at least have consistent times for my database entries.
bump, just encountered this limitation.
Key directive must be able to accept nulls to allow autoid, server createdAt and updatedAt
related to https://github.com/aws-amplify/amplify-cli/pull/356
I've always had trouble retrieving createdAt
because it isn't in the autogenerated schema and I think there might have been a resolver issue at one point. Are you able to retrieve createdAt
?
Edit: confirmed access issue - #401
I've created https://github.com/hirochachacha/graphql-auto-transformer for solving these kinds of problems.
Usage:
type Item @model @key(fields: ["id", "createdAt"]){
id: ID!
createdAt: String! @auto
}
It turned out that amplify's import mechanism is broken. https://github.com/aws-amplify/amplify-cli/pull/3236
So above approach doesn't work right now.
@hirochachacha Your transformer works again, since the issue above was resolved and merged about two weeks ago. However, when I use three field values, the composite key cannot not retrieve the autogenerated value.
E.g., this model
type ChatMessageV2 @model @key(fields: ["projectId", "createdAt", "sender"])
{
id: ID!
message: String
type: ChatMessageType
projectId: String!
createdAt: AWSDateTime! @auto
updatedAt: AWSDateTime
sender: String!
}
generates a correct looking Create mutation, however, when using it, it results in DB entries that look like this:
{
"__typename": "ChatMessageV2",
"createdAt": "2020-05-23T12:55:09.630Z",
"createdAt#sender": "${ctx.args.input.createdAt}#hanna",
"message": "Hello",
"projectId": "2889e7fc-53b2-4807-a862-e8898f5e1ebd",
"sender": "hanna",
"updatedAt": "2020-05-23T12:55:09.630Z"
}
As you can see, the "createdAt#sender" field is still trying to retrieve the createdAt value from the input, instead of using the auto-generated one. Is this something you could fix easily?
I am using the latest amplify-cli version (4.20.0).
@hanna-becker I've released 1.3.0 which might solve your problem.
This fix is released in Amplify CLI v4.21.1
@hirochachacha Hi
I used your transformer but got an error when trying a basic mutation
I looked in the resolver and it seems the code generated as a little bug
$util.qr($context.args.input.put("createdAt", $util.defaultIfNull($ctx.args.input.createdAt, util.time.nowISO8601())))
missing a '$' before util.time.nowISO8601
@TheUncharted Fixed. Thanks for pointing it out. BTW, If you find specific issues about the plugin, please report at https://github.com/hirochachacha/graphql-auto-transformer/issues instead. Thanks.
Most helpful comment
I've created https://github.com/hirochachacha/graphql-auto-transformer for solving these kinds of problems.