Amplify-cli: using createdAt as a sortKey in @key directive results mandatory id and createdAt fields in CreateItemInput and CreateItem mutation in GraphQL Transform

Created on 13 Jun 2019  路  13Comments  路  Source: aws-amplify/amplify-cli

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
}
feature-request graphql-transformer

Most helpful comment

I've created https://github.com/hirochachacha/graphql-auto-transformer for solving these kinds of problems.

All 13 comments

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.

Was this page helpful?
0 / 5 - 0 ratings