I tried to use example schema on api doc("https://aws-amplify.github.io/docs/cli-toolchain/graphql?sdk=js") like below on Many-To-Many Connections
type Post #model {
id: ID!
title: String!
editors: [PostEditor] #connection(keyName: "byPost", fields: ["id"])
}
# Create a join model and disable queries as you don't need them
# and can query through Post.editors and User.posts
type PostEditor
#model(queries: null)
#key(name: "byPost", fields: ["postID", "editorID"])
#key(name: "byEditor", fields: ["editorID", "postID"]) {
id: ID!
postID: ID!
editorID: ID!
post: Post! #connection(fields: ["postID"])
editor: User! #connection(fields: ["editorID"])
}
type User #model {
id: ID!
username: String!
posts: [PostEditor] #connection(keyName: "byEditor", fields: ["id"])
}
I created all items and then I tried to delete them but I failed especially on PostEditor.
There is a mutation to delete PostEditor so I called it like below
API.graphql(graphqlOperation((deletePostEditor, {input: {id},})))
It fails with below error message.
Error: Invalid AST Node: {"input":"b2f7064c-af32-49cd-8c87-*******"}
I think I provided right ID. I checked it on query.
You should pass your parameters as a second parameter of graphqlOperation. so , check your parentheses
API.graphql(graphqlOperation((deletePostEditor, {input: {id},}))),you have one pair extra parenthesis
below is correct one
API.graphql(graphqlOperation(deletePostEditor, { input: { id } }))
first param=deletePostEditor
second param={ input: { id } }
tiny mistake, Isn't It?
Related
I just tried to implement the Relay in Frontend for this graphql tutorial, In that tutorial, they created graphql server to store URL(Link) bookmarks with the User who posted those URLs.
The relationship between the link and the users is:
Link belongs_to :user,
User has_many :links.
And I listed out all the Links with Users in Frontend, at the time I got the below error.
Warning: RelayResponseNormalizer: Invalid record 1. Expected __typename to be consistent, but the record was assigned conflicting types Link and User. The GraphQL server likely violated the globally unique id requirement by returning the same id for different objects
I'm not aware of how much it will impact the application. because I got the expected result from Frontend.
Frontend View of Query.
I read this relay official blog for this kind of error, but there is no example to know how exactly to resolve this. so can someone help to resolve this?
Relay Query
graphql`
query LinkListQuery {
allLinks {
id,
description,
url,
postedBy {
id,
name
}
}
}`
Schema:
input AUTH_PROVIDER_CREDENTIALS {
email: String!
password: String!
}
input AuthProviderSignupData {
credentials: AUTH_PROVIDER_CREDENTIALS
}
type Link implements Node {
description: String!
id: ID!
postedBy: User
url: String!
votes: [Vote!]!
}
input LinkFilter {
OR: [LinkFilter!]
descriptionContains: String
urlContains: String
}
type Mutation {
createLink(description: String!, url: String!): Link!
createUser(name: String!, authProvider: AuthProviderSignupData): User!
createVote(linkId: ID): Vote!
signinUser(credentials: AUTH_PROVIDER_CREDENTIALS): SignInUserPayload
}
"""An object with an ID."""
interface Node {
"""ID of the object."""
id: ID!
}
type Query {
allLinks(filter: LinkFilter, first: Int, skip: Int): [Link]!
"""Fetches an object given its ID."""
node(
"""ID of the object."""
id: ID!
): Node
}
"""Autogenerated return type of SignInUser"""
type SignInUserPayload {
token: String
user: User
}
type User implements Node {
email: String!
id: ID!
links: [Link!]!
name: String!
votes: [Vote!]!
}
type Vote {
id: ID!
link: Link!
user: User!
}
I am new to Amplify and I am trying to set up a fairly complex schema. When I run amplify push, the only response that I get is ...
An error occurred when pushing the resources to the cloud
This happens after the notice that it will create the resources and I am asked if I want to continue. I deleted most of the schema and tried again with just one model and it worked, so there is a problem somewhere in my schema ... I guess? I don't see anywhere to check it.
Here is the schema
type Article
#model
#key(name: "bySource", fields: ["sourceId", "dateWritten"]) {
id: ID!
link: AWSURL!
title: String!
dateWritten: String!
createdAt: String!
data: AWSJSON!
approved: Boolean!
admin: Boolean!
creatorId: ID!
creator: User #connection(fields: ["creatorId"])
sourceId: ID!
source: Source #connection(fields: ["sourceId"])
tagArtCons: [TagArtCon]
#connection(keyName: "byArticle", fields: ["articleId"])
}
type Tag #model #key(name: "byFrontPage", fields: ["frontpage"]) {
id: ID!
name: String!
createdAt: String!
creatorId: ID!
data: AWSJSON!
frontpage: String
official: Boolean!
tagArtConns: [TagArtCon] #connection(keyName: "byTag", fields: ["tagId"])
}
type TagArtCon
#model
#key(name: "byTag", fields: ["tagId"])
#key(name: "byArticle", fields: ["articleId"]) {
id: ID!
tagId: ID!
articleId: ID!
creatorId: ID!
createdAt: String!
article: Article #connection(fields: ["articleId"])
tag: Tag #connection(fields: ["tagId"])
parentRelations: [TagRelation]
#connection(keyName: "byParent", fields: ["tagId"])
childRelations: [TagRelation]
#connection(keyName: "byChild", fields: ["tagId"])
}
type TagRelation
#model
#key(name: "byParent", fields: ["parentId"])
#key(name: "byChild", fields: ["childId"]) {
id: ID!
parentId: ID!
childId: ID!
creatorId: ID!
createdAt: String!
parentTag: Tag #connection(fields: ["parentId"])
childTag: Tag #connection(fields: ["childId"])
}
type Source #model {
id: ID!
sourceName: String!
sourceUrl: String!
sourceImage: String!
creatorId: ID!
articles: [Article] #connection(keyName: "bySource", fields: ["id"])
}
type User #model {
id: ID!
userName: String!
userImage: String!
admin: Boolean!
createdAt: String!
data: AWSJSON
}
What I am trying to do is have a bunch of articles and a bunch of tags. The tags represent categories, people, etc. I have the following tables
articles,
tags,
a table where each entry ties an article to a tag
a table of relations between tags where parent/child relationships are held
a source table that just holds data for the sources of the articles
a user table
I've made a mistake somewhere and the schema isn't working and it isn't telling me why. I'm gonna keep simplifying this until I can hope to nail down the problem, but I would really appreciate any help as I am new to this. Thanks.
Finally found the problem(s). There is a place where I try to use "articleId" and a place where I try to use "tagId" and both should be "id".
I'm working on Next.js and Amplify together, trying to get sorting to work with the database.
Why can't we just sort by DESC or ASC a list of queries? Why do we have to create a new key and add an additional fields to it?
like for example:
type Order #model #key(fields: ["customerEmail", "createdAt"]) {
id: ID!
customerEmail: String!
createdAt: String!
orderId: ID!
}
Would allow your to get all the orders with customerEmail, and then you can do sortDirection, and this will only work if you have another field like customerEmail to populate:
await API.graphql(listOrders, {
customerEmail: "some#email.com",
sortDirection: "DESC", // or ASC
})
This will give you the list of orders from some#email.com and it will allow you to sort.
Why can't we just have the id field, and sort:
type Order #model #key(name: "orderSort", fields: ["id", "createdAt"], queryField: "orderSort") {
id: ID!
customerEmail: String!
createdAt: String!
orderId: ID!
}
and sorting the list:
await API.graphql(orderSort, {
sortDirection: "DESC", // or ASC
})
I tried something similar to this, and I get an error: Expression block '$[query]' requires an expression.
Or why can't we just do sorting even without the #key directive, just have the listOrders with sortDirection:
type Order #model {
id: ID!
customerEmail: String!
createdAt: String!
orderId: ID!
}
await API.graphql(listOrders, {
sortDirection: "DESC", // or ASC
})
Dynamodb SCAN operator doesn't guarantee the order.
Currently, Amplify also doesn't support sorting by default.
However, apparently, what most people do is adding a constant field to the model.
type Order #model #key(name: "orderSort", fields: ["typename", "createdAt"], queryField: "orderSort") {
id: ID!
customerEmail: String!
typename: String! # for example, Order in this case
createdAt: AWSDateTime!
}
await API.graphql(orderSort, {
typename: "Order",
sortDirection: "DESC", // or ASC
})
I am beginning a project with Amplify DataStore and modeling data that has a many-to-many relationship that also requires authorization. I'm having a hard time finding examples of M2M with auth, there are none in the documentation.
Here is a MTM example from the DataStore docs, I want to prevent users that are not PostEditors from being able to load Posts. Currently the plan is to use Cognito, but open to other solutions. How would this be achieved?
type Post #model {
id: ID!
title: String!
editors: [PostEditor] #connection(keyName: "byPost", fields: ["id"])
}
type PostEditor
#model(queries: null)
#key(name: "byPost", fields: ["postID", "editorID"])
#key(name: "byEditor", fields: ["editorID", "postID"]) {
id: ID!
postID: ID!
editorID: ID!
post: Post! #connection(fields: ["postID"])
editor: User! #connection(fields: ["editorID"])
}
type User #model {
id: ID!
username: String!
posts: [PostEditor] #connection(keyName: "byEditor", fields: ["id"])
}
Let's take an example from the github repo of prisma:
We have a user, the user could have multiple posts, and one post could have multiple links.
My goal is, to retrieve all posts and all links.
This means, my response is a list (links) in a list (posts).
I want to map the values I get back as two nested lists.
datamodel.prisma
type User {
id: ID! #id
email: String! #unique
name: String
posts: [Post]!
}
type Post {
id: ID! #id
createdAt: DateTime! #createdAt
updatedAt: DateTime! #updatedAt
published: Boolean! #default(value: false)
title: String!
content: String
author: User!
links: [Link]!
}
type Link {
id: ID! #id
url: String
title: String
post: Post!
}
schema.graphql
type Query {
...
}
type Mutation {
...
}
type Link {
id: ID!
url: String
title: String
post: Post!
}
type Post {
id: ID!
createdAt: DateTime!
updatedAt: DateTime!
published: Boolean!
title: String!
content: String
author: User!
}
type User {
id: ID!
email: String!
name: String
posts: [Post]!
}
I want to query all posts of a user, and all of the links for every post in the response.
How would I query this request?
user {
id
posts {
id
links {
id
}
}
}
The above code snipper would not work.
EDIT
I want to use the following:
User: {
listPosts: (parent, args, context, info) {
return context.prisma.posts().links()
}
}
So in my response (data in front-end via react-apollo Query Component), I want to map over posts AND the links in each post.
BUT the links attribute in posts is null.
Is there another way to achieve this?!
According to the docs:
Prisma client has a fluent API to query relations in your database. Meaning you can simply chain your method calls to navigate the relation properties of the returned records. This is only possible when retrieving single records, not for lists. Meaning you can not query relation fields of records that are returned in a list.
In order to get around that limitation, you can use the $fragment method:
const fragment = `
fragment UserWithPostsAndLinks on User {
id
email
name
posts {
id
title
content
links {
id
url
title
}
}
}
`
const userWithPostsAndLinks = await prisma.user({ id: args.id }).$fragment(fragment)