DynamoDB AppSync field resolvers timing out - amazon-web-services

So I have the schema below. If I try to query data off this schema AppSync will time out saying 'NetworkError when attempting to fetch resource.'
type Model {
PartitionKey: ID!
SortKey: ID!
Name: String
Version: Int
FBX: String
# ms since epoch
CreatedAt: AWSTimestamp
Description: String
Tags: [Tag]
}
type ImageSet {
PartitionKey: ID!
SortKey: ID!
Name: String
CreatedAt: AWSTimestamp
Description: String
Tags: [String]
}
Now, if I change 'Name' in the model to 'ModelName' then queries on that will work. If I change 'Name' in ImageSet to 'SetName' then queries on that will work.
What is going on with this? What is wrong with the 'Name' field name? 'Description' and 'CreatedAt' do not have this issue.
Edit
Actually I am encountering this happening with other fields in the
schema as well. Please help.
I do have resolvers attached to specific fields. Removing them does
solve the problem. Am I not supposed to attach revolvers to specific
fields or is something else wrong?
-
Edit 2
This really does seem to only occur if the name of a field is shared
between different schema objects, is that not allowed!?

Related

Not being able to edit my Many-To-Many entity in AWS AppSync

When creating a Many-to-Many relationship using GraphQL for the schema, I have been unable to alter the entity created. The #manyToMany annotation enables the syntax to produce a table named "OrderUsers". But the problem lies in my inability to alter the "OrderUsers" entity. After different attempts at changing the table, I have been unable to figure out how to change it. The only attributes that are taken into the "OrderUsers" table are the id from both the User as well as Order table, which also creates only two GSIs. Also, this is using the v2 docs.
type User #model {
id: ID!
fName: String!
lName: String!
phoneNumber: String!
email: String!
DOB: String!
orders: [Order] #manyToMany(relationName: "OrderUsers")
ordersByDate: [Order] #hasMany(indexName: "byOrderByDate", fields: ["id"])
ordersByStatusDate: [Order] #hasMany(indexName: "byOrderStatusByDate", fields: ["id"])
}
type Order #model {
id: ID!
userId: ID! #index(name: "byOrderStatusByDate", sortKeyFields: ["status", "date"]) #index(name: "byOrderByDate", sortKeyFields: ["date"])
status: String!
amount: Int
date: String!
users: [User] #manyToMany(relationName: "OrderUsers") # Test to see if I can tinker w/ the 'OrderUsers' tbl
productId: ID! #index(name: "byProductOrder", sortKeyFields: ["id"])
clubId: ID! #index(name: "byClub", sortKeyFields: ["id"])
}
After reviewing the AWS Amplify as well as AppSync docs, attempting to add GSIs to the 'OrderUsers' table, switch the partition key used from the 'User' entity to a composite partition key for the 'OrderUsers' table, and adding other attributes to the 'OrderUsers' table, everything gets wiped as I try to push/pull it. Since the syntax isn't stored in the schema.graphql file, I have been stuck. My expectation was that it would save into the schema and update the resolvers used for the mutation(s) & queries, but that has not been the case.
Any and all help would be appreciated,
Thank you & Happy holidays

Validate user input in AppSync DynamoDB Resolvers

I have AWS AppSync API with DynamoDb and I can create and get data from it with DynamoDb Resolvers. (VTL templates)
I am not sure how can I do the user input validation with VTL templates. I want to make sure the contact's "firstName" is between 2 - 30 characters in length.
How can I achieve this with VTL? Is there a way to do this kind of validation within the GraphQL schema itself?
Here's my GraphQL Schema,
schema {
query: Query
mutation: Mutation
}
type Mutation {
createContact(contact: ContactInput!): Contact!
}
type Contact {
contactId: ID!
firstName: String!
lastName: String!
email: String!
}
input ContactInput {
firstName: String!
lastName: String!
email: String!
}
I can't find a nice way of doing this in GraphQL, but you can do it easily in VTL using either $util.validate or $util.error (see the AWS documentation). They both have the same result of adding an item to the errors array.
Here's a demo of $util.validate:
https://mappingtool.dev/app/appsync/bee55bd607e2166091451e7a7959318e
Here's a demo of $util.error:
https://mappingtool.dev/app/appsync/006d6c05e8bb7257c6cebce34494994c

How to sort and filter by createdAt and updatedAt in aws AppSync?

I used AWS Amplify to create an GraphQL API. In DynamoDB the fields createdAt and updatedAt are created automatically. I have no way of filter values for this fields with Appsync. I would like to query data with appsync with filter range between two createdAt field but it doesn't appear in my appsync query schema.
So how can I do a query with createdAt filter or sort?
This is an AWS-Amplify specific question. It's not about how to do this with generic GraphQL.
I found the solution finally.
You have to add auto generated fields "createdAt" and "updatedAt" directly on the schema.graphql
Like that:
According to this inital schema.graphql:
type User #model(timestamps: { createdAt: "createdOn", updatedAt: "updatedOn" })
{
id: String!
username: String!
firstName: String!
lastName: String!
}
It will become:
type User #model
{
id: String!
username: String!
firstName: String!
lastName: String!
createdAt: AWSDateTime! #important to keep it to have filter with keys
updatedAt: AWSDateTime! #important to keep it to have filter with keys
}
After the amplify push, we can get items by date directly, simply like that:
query MyQuery {
listUsers(filter: {updatedAt: {between: ["2021-04-29T16:02:21.285Z", "2021-05-29T16:02:21.285Z"]}}) {
items {
id
lastName
}
}
}

How to store multiple key values in an Array on one field

I have a football team model as seen here
type Team #model
{
id: ID!
name: String!
faId: ID!
seasonID: ID!
seasons: [seasonID] #connection(fields: ["seasonID"])
}
The team will play in multiple seasons. I would like to store the data in a array
seasonID: [ID]!
Then when fetching the data, I can return all the seasons the Team was a part of.
Is this possible with Dynamodb. When I try to say it this way it says:
InvalidDirectiveError: All fields provided to an #connection must be non-null scalar or enum fields.
InvalidDirectiveError: All fields provided to an #connection must be non-null scalar or enum fields. means that the part where you have [seasonID] should not be any of the typs ID, String, Int etc as shown & described here
The connection for cardinality One-To-Many 1..* you are trying to do there would be achieved by creating a separate model called Season. eg:
# Separate model for Season
type Season #model{
id: ID!
name: String!
}
type Team #model
{
id: ID!
name: String!
faId: ID!
seasonID: ID!
seasons: [Season] #connection(fields: ["seasonID"])
}
You can see a example of more you can do here

Can I have camel case as default when using postgres in loopback?

If you don't specify anything all the fields are created as lower case in the database when using postgres. Is it possible to change the default behavior to use the exact name of the fields in the model? That makes it easier to write custom queries.
As it is now I have to configure the property on each field to say that they should be camel case, and that is quite error prone since that is something that is easy to forget.
If that isn't possible, is it possible to use the functionality in the repository that does the mapping from all lowercase to the fields in the models in an easy manner somehow?
Not sure if this helps, but you can use name property
example:
export class User extends .... { #property({
type: 'number',
id: true, }) id?: number;
#property({
type: 'string',
required: true,
name: 'first_name',
})
firstName: string;
#property({
type: 'string',
name: 'last_name',
})
lastName: string;