What happens is the following, I have this table in GraphQL:
type Purchase #model #auth(rules: [{allow: private}]) {
id: ID!
date: AWSTime!
product: Product!
}
type Product #model #auth(rules: [{allow: private}]) {
id: ID!
name: String
price: double
}
Suppose I delete the product so users can't search for it. But when the user goes to their purchase history, I want them to see the product details.
Is there any way I can reference a deleted recording, but not a direct query to it?
Related
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
I have issues when creating a schema for Amplify/graphql. I have one type called Employee and one type called Station. An Employee can work on multiple stations and vice versa. Which alternative do you think I should choose?
Here I simply look for the station ids and create an array as station ids. No real connection.
type Station #model #auth(rules: [{ allow: public }]) {
stationName: String!
id: ID
}
type Employee #model #auth(rules: [{ allow: public }]) {
id: ID
employeeName: String!
stationIds: [String]
}
I tried this but had problems register the stations field in Employees. Tried some custom inputs but I am not sure how to do it.
type Station #model #auth(rules: [{ allow: public }]) {
stationName: String!
id: ID
}
type Employee #model #auth(rules: [{ allow: public }]) {
id: ID
employeeName: String!
stations: [Station]
}
My current solution but I don't know if its overkill?
type Station #model #auth(rules: [{ allow: public }]) {
stationName: String!
id: ID
employees: [Employee] #manyToMany(relationName: "StationEmployee")
}
type Employee #model #auth(rules: [{ allow: public }]) {
id: ID
employeeName: String!
stations: [Station] #manyToMany(relationName: "StationEmployee")
}
Your current solution (3) appears to be correct based on the Amplify documentation
I'd also recommend making the ID non-nullable for both types, i.e. 'ID!'
In your first solution you used a SQL-like pattern by referring to IDs instead of types, stationIds: [String] is a counter-pattern in GraphQL since you require multiple queries to get all the results you wanted and you'd have to stitch them together by yourself.
I have a small graphQL structure like this for AWS but when I try to push it throws me an error saying
✖ An error occurred when pushing the resources to the cloud
#connection must be on an #model object type field.
Please help to understand where I am making mistakes.
Is there any VS code extension to debug this?
type Store {
id: ID!
products: [Product] #connection(name: "StoreProducts")
}
type Product #model #searchable {
id: ID!
name: String!
description: String!
price: Float!
isOnCourse: Boolean!
isOnOutlet: Boolean!
store: Store #connection(name: "StoreProducts", sortField: "crearedAt")
file: S3Object!
}
type S3Object {
bucket: String!
region: String!
key: String!
}
type User
#model(
queries: { get: "getUser" }
mutations: { create: "registredUser", update: "updateUser" }
subscriptions: null
) {
id: ID!
username: String!
email: String!
phoneNumber: String!
registred: Boolean
orders: [Order] #connection(name: "UserOrders", sortField: "createdAt")
}
type Order
#model(
queries: null
mutations: { create: "createOrder" }
subscriptions: null
) {
id: ID!
product: Product #connection
user: User #connection(name: "UserOrders")
orderLocation: OrderLocation
crearedAt: String
}
type OrderLocation {
tableNumber: String
qrData: String
holeNumber: String
}
When you create a relation on type Product
store: Store #connection(name: "StoreProducts", sortField: "crearedAt")
You have to tell server how to look for the items. by which field name. That is why you are getting this error "#connection must be on an #model object type field."
Solution would be add fields. On type Product if you want to bring Store Products, you need to add "id" fields.
store: Store #connection(name: "StoreProducts", fields:["id"] sortField: "crearedAt")
In all other types if you want to have relation, you have to define a convenient field to query the data.
AWS amplify DynamoDB Graph QL filter by book title and author name
i want to search books by book title and author name but my schema allow me to search books by book title and author ID not author name how i can achieve this.
following is my graph ql schema
type Author
#model(subscriptions: null)
#auth(
rules: [
# allow admins to create, update and delete books
{ allow: groups, groups: ["owner"] }
# allow all authenticated users to view books
{ allow: private, operations: [read] }
]
)
#key(name: "authorByCreatedAt", fields: ["isDeleted", "createdAt"], queryField: "authorByCreatedAt")
{
id: ID!
name: String!
description: String!
status : Boolean!
createdAt: String!
image: String!
isDeleted: Int!
books: [Book] #connection(keyName: "byAuthor", fields: ["id"])
}
type Book
#model(subscriptions: null)
#auth(
rules: [
# allow admins to create, update and delete books
{ allow: groups, groups: ["owner"] }
# allow all authenticated users to view books
{ allow: private, operations: [read] }
]
)
#key(name: "bookByCreatedAt", fields: ["isDeleted", "createdAt"], queryField: "bookByCreatedAt")
#key(name: "byAuthor", fields: ["authorId"])
{
id: ID!
title: String!
description: String!
image: String!
age: Int!
region: String!
isbn: String
narrator: String
status : Boolean!
createdAt: String!
isDeleted: Int!
book: String!
bookType: BookType!
authorId: ID!
authors: Author #connection(fields: ["authorId"])
}
enum BookType {
AUDIO
EPUB
}
If you are coming from the world of relational databases, this might seem like it should be trivial. In the world of DynamoDB it is more complex. You cannot create a #key that is linked to a #connection ( as far as I understand ). Some solutions to this problem:
1: Add Author's Name to Book
The author's name doesn't change typically, so you could do the below. Duplicating data is not frowned upon in DynamoDB/NoSQL world. This will give you a faster query as well.
type Book
#model(subscriptions: null)
#key(name: "BooksByAuthorName", fields: ["authorName"], queryField: "getBooksByAuthorName")
{
id: ID!
title: String!
description: String!
image: String!
age: Int!
region: String!
isbn: String
narrator: String
status : Boolean!
createdAt: String!
isDeleted: Int!
book: String!
bookType: BookType!
authorId: ID!
authorName: String
authors: Author #connection(fields: ["authorId"])
}
2: Custom Resolvers
Custom resolvers, like #function ( Lambda functions ), or the more complex custom resolver templates can be used for multiple searches, and custom logic, though I would suggest option 1 first.
3: Exploring #searchable directive
See this for more info
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