I have the following GraphQL schema. It has Books and Authors with a many to many relationship. How do I create a new Book mutation for an existing Author?
schema
type Author implements Node {
books: [Book!]! #relation(name: "BookAuthors")
createdAt: DateTime!
id: ID! #isUnique
name: String!
updatedAt: DateTime!
}
type Book implements Node {
authors: [Author!]! #relation(name: "BookAuthors")
createdAt: DateTime!
id: ID! #isUnique
title: String!
updatedAt: DateTime!
}
mutation
mutation CreateBook($title: String!, $authors: [Author!]) {
createBook(
title: $title,
authors: $authors,
) {
id
title
}
}
variables
{
"title": "Ryans Book",
"authors": ["cj5xti3kk0v080160yhwrbdw1"]
}
This is apparently called a 'connect mutation'.
https://www.graph.cool/docs/reference/simple-api/nested-connect-mutations-tu9ohwa1ui/
mutation CreateBook($title: String!, $authorIds: [ID!]) {
createBook(
title: $title,
authorIds: $authorIds,
) {
id
title
}
}
Related
Working with amplify datastore and edited schema.graphql as following and when I enter "amplify codegen models" I get this error "Error: Expected scalar and got User" However the code was generated successfully. How would I be able to fix this error?
type User
#model
#key(name: "ByEmail", fields: ["email"], queryField: "userByEmail")
#auth(rules: [{ allow: owner }]) {
id: ID!
email: String!
gender: String!
birthdate: String!
faceImage: String
favoriteAvatar: [Avatar] #connection(fields: ["avatarId"])
totalVideoTransform: Int
registerAt: AWSDateTime!
}
type Avatar
#model
#key(name: "ByAvatrId", fields: ["avatarId"], queryField: "avatarByAvatarId")
#auth(rules: [{ allow: owner, ownerField: "favoriteUser", operations: [create, update, read] }]) {
id: ID!
avatarId: String!
gender: String!
favoriteUser: [User] #connection(fields: ["email"])
totalVideoTransform: Int
}
type UserLoginLog
#model
#key(name: "ByUser", fields: ["user"], queryField: "userLoginLogByUser")
#auth(rules: [{ allow: owner, operations: [create] }]) {
id: ID!
user: User #connection(fields: ["email"])
loginAt: AWSDateTime!
}
type VideoTransformLog
#model
#key(name: "ByUser", fields: ["user"], queryField: "videoTransformLogByUser")
#auth(rules: [{ allow: owner, operations: [create] }]) {
id: ID!
user: User #connection(fields: ["email"])
avatar: Avatar #connection(fields: ["avatarId"])
videoTransformAt: AWSDateTime!
}
In your types "UserLoginLog" and "VideoTransformLog", remove "user" from the #key(... fields).
So don't place names that correspond to a type in fields[].
So I have 3 collections in my schema
type User #model(subscriptions: null) {
id: ID!
name: String
email: String
events: [EventUser] #connection(keyName: "byUser", fields: ["id"])
}
type Event #model
#key(name: "byApiKey", fields: ["apiKey"])
#key(name: "byOrganization", fields: ["organizationID"], queryField: "eventByOrganization")
{
id: ID!
apiKey: ID!
title: String
participants: [EventUser] #connection(keyName: "byEvent", fields: ["id"])
}
type EventUser #model
#key(name: "byUser", fields: ["userID"], queryField: "eventByUser")
#key(name: "byEvent", fields: ["eventID"], queryField: "userByEvent") {
id: ID!
userID: ID!
eventID: ID!
user: User! #connection(fields: ["userID"])
event: Event! #connection(fields: ["eventID"])
}
And I am trying to search the EventUser collection by eventID and user.name. Is there some piece of amplify that can enable me search by the user.name and return the EventUser collection?
I set up prisma with a graphql yoga server and have both GraphQL playgrounds available.
I could successfully create a conversation that I'm now trying to retrieve. I can't get this simple resolver to work in the Yoga GraphQL Playground:
const resolvers = {
Query: {
conversation(parent: any, { id }: { id: string }, { prisma }: Context) {
return prisma.conversation( { id } )
}
},
Mutation: mutation
}
I used this query:
query getConversation {
conversation(where: {
id: "cjrqzinj4004e0a30ch4pccml"
}) {
id
title
}
}
Error message is:
{
"data": {
"conversation": null
},
"errors": [
{
"message": "You provided an invalid argument for the where selector on Conversation.",
"locations": [
{
"line": 2,
"column": 3
}
],
"path": [
"conversation"
],
"code": 3040,
"requestId": "local:cjrsahjoo00ai0a30a5y8mnvp"
}
],
"extensions": {}
}
The query works in the Prisma GraphQL playground.
Here is my data model:
type User {
id: ID! #unique
oauthId: String! #unique
display: String!
picture: String!
likes: [Comment!]! #relation(name: "Likes")
dislikes: [Comment!]! #relation(name: "Dislikes")
bookmarks: [Comment!]! #relation(name: "Bookmarks")
authorOf: [Comment!]! #relation(name: "Author")
starterOf: [Conversation!]! #relation(name: "Starter")
}
type Attachment {
id: ID! #unique
name: String!
createOn: DateTime!
mediaType: String!
comment: Comment! #relation(name: "Attachments")
}
type Comment {
id: ID! #unique
author: User! #relation(name: "Author")
content: String!
createDate: DateTime!
parentConversation: Conversation #relation(name: "Conversation")
parentComment: Comment #relation(name: "Replies")
comments: [Comment!]! #relation(name: "Replies")
bookmarkedBy: [User!]! #relation(name: "Bookmarks")
likedBy: [User!]! #relation(name: "Likes")
dislikedBy: [User!]! #relation(name: "Dislikes")
attachments: [Attachment!]! #relation(name: "Attachments")
}
enum ParentType {
Organization,
Portfolio,
Project,
WbsComponent,
WorkItem
}
type Parent {
id: ID! #unique
parent: String! #unique
type: ParentType!
conversations: [Conversation!]! #relation(name: "Parent")
}
type Conversation {
id: ID! #unique
parent: Parent! #relation(name: "Parent")
organization: String!
title: String!
author: User! #relation(name: "Starter")
createdOn: DateTime!
comments: [Comment!]! #relation(name: "Conversation")
}
Can try to pass where property to the prisma client
const resolvers = {
Query: {
conversation(parent: any, { id }: { id: string }, { prisma }: Context) {
return prisma.conversation( { where: { id } )
}
},
Mutation: mutation
}
I got the answer from the Prisma forum. I was doing my destructuring wrong (note that ConversationWhereUniqueInput is a type provided by prisma):
export const conversation = (
parent: any,
{ where: { id } }: { where: ConversationWhereUniqueInput },
{ prisma }: Context
): ConversationPromise => {
return prisma.conversation({ id })
}
I'm trying to learn GraphQL (& node.js & MongoDB etc.). I cant get this simple nested query to return results :
query getLocationByPerson {
People {
firstName
lastName
service {
location
}
}
}
I only get the first level fields, like:
{
"data": {
"People": [
{
"firstName": "xxx",
"lastName": "XXXXX",
"service": null
}
}
Here's my schema:
type Query {
People: [PeopleObject]!
PeopleByName(lastName: String!): [PeopleObject]
PeopleByID(id:ID!): [PeopleObject]
Service: [ServiceObject]
ServiceByID(id:ID!): [ServiceObject]
}
type PeopleObject {
id: ID!
Xid: String!
firstName: String!
lastName: String!
email: String!
serviceId: String
apps: [String]
service: [ServiceObject]
}
type ServiceObject {
id: ID!
name: String!
location: String!
}
And my resolver:
const queries = {
People: () => People.find({}),
PeopleByName: (root,args,context,info) => People.find({lastName: args.lastName}),
PeopleByID: (root,args,context,info) => People.find({_id: args.id}),
Service: () => Service.find({}),
ServiceByID: (root,args,context,info) => Service.find({_id: args.id})
};
Any idea what am I doing wrong?
You need to pass the reference for the location object in service which is same as you mongoose model(i assume you are using mongoose). After passing the reference you can add populate(refernce).exec() in your service query Refer this
Your syntax are dame good for getting any data from graphql
type Query {
People: [PeopleObject]!
}
type PeopleObject {
id: ID!
Xid: String!
firstName: String!
lastName: String!
email: String!
serviceId: String
apps: [String]
service: [ServiceObject]
}
type ServiceObject {
id: ID!
name: String!
location: String!
}
for Simplicity
type Query {
People: [{
id: ID!
Xid: String!
firstName: String!
lastName: String!
email: String!
serviceId: String
apps: [String]
service: [{
id: ID!
name: String!
location: String!
}]
}]!
}
But you have return only people
People: () => People.find({}),
You should return service array object to get that return object with People
People: () => return something Like below result.
[{
id: '5c5ac87e5e4d85ae77de9c50'
Xid: 'xx'
firstName: 'yyy'
lastName: 'zzz'
email: 'xxx#gmail.com'
serviceId: '5c5ac87e5e4d85ae77de9c51'
apps: ['testing', 'google']
service: [{
id: 5c5ac78d5e4d85ae77de9c4f,
name: 'Tester',
location: 'US America',
}, {}]
}, {}]
If you using mongoose use aggregation to get data from mongoBD.
Running prisma generate I encurred in this output and no code is generated.
prisma generate
Generating schema...
[ { species: { type: [Object], args: [Object] } },
{ species: { type: [Object], args: [Object] },
Generating schema !
! Field configuration to merge has duplicate field names.
What's wrong with my schema?
type User {
id: ID! #unique
email: String! #unique
name: String!
password: String!
entries: [Entry!]!
createdAt: DateTime!
updatedAt: DateTime!
}
type Language {
id: ID! #unique
language: String! #unique
createdAt: DateTime!
updatedAt: DateTime!
}
type EntryScientificName {
id: ID! #unique
entry: Entry!
isMain: Boolean!
scientificName: String! #unique
language: Language!
createdAt: DateTime!
updatedAt: DateTime!
}
type EntryName {
id: ID! #unique
entry: Entry!
isMain: Boolean!
name: String! #unique
Language: Language!
createdAt: DateTime!
updatedAt: DateTime!
}
type Species {
id: ID! #unique
species: String! #unique
description: String
createdAt: DateTime!
updatedAt: DateTime!
}
type Genus {
id: ID! #unique
genus: String! #unique
description: String
createdAt: DateTime!
updatedAt: DateTime!
}
type Family {
id: ID! #unique
family: String! #unique
description: String
createdAt: DateTime!
updatedAt: DateTime!
}
type Order {
id: ID! #unique
order: String! #unique
description: String
createdAt: DateTime!
updatedAt: DateTime!
}
type Habitat {
id: ID! #unique
habitat: String! #unique
description: String
createdAt: DateTime!
updatedAt: DateTime!
}
type Month {
id: ID! #unique
month: String! #unique
}
type Anthesis {
id: ID! #unique
entry: Entry
fromMonth: Month! #relation(name: "FromMonth")
toMonth: Month! #relation(name: "ToMonth")
note: String
createdAt: DateTime!
updatedAt: DateTime!
}
type Nation {
id: ID! #unique
nation: String! #unique
createdAt: DateTime!
updatedAt: DateTime!
}
type Region {
id: ID! #unique
nation: Nation!
region: String! #unique
createdAt: DateTime!
updatedAt: DateTime!
}
type DistributionDetail {
id: ID! #unique
detail: String!
createdAt: DateTime!
updatedAt: DateTime!
}
type GeographicDistribution {
id: ID! #unique
entry: Entry!
region: Region!
detail: DistributionDetail
createdAt: DateTime!
updatedAt: DateTime!
}
type Altitude {
id: ID! #unique
entry: Entry! #unique
altitudeFrom: Int! #unique #constraint(min: -10894, max: 408000)
altitudeTo: Int! #unique #constraint(min: -10894, max: 408000)
}
type Entry {
id: ID! #unique
name: [EntryName!]!
scientificName: [EntryScientificName!]!
species: Species
genus: Genus
family: Family
order: Order
biologicalForm: String
plantDescription: String
leafDescription: String
flowerDescription: String
fruitDescriptio: String
chorologicalType: String
habitat: [Habitat!]!
geographicDistribution: [GeographicDistribution!]!
altitude: [Altitude!]!
etymology: String
propertiesUses: String
curiosities: String
notes: String
links: [Link!]!
entryPicture: String
draft: Boolean #default(value: "true")
published: Boolean #default(value: "false")
toBeReviewed: Boolean #default(value: "false")
createdAt: DateTime!
updatedAt: DateTime!
author: User
}
type Link {
id: ID! #unique
createdAt: DateTime!
updatedAt: DateTime!
url: String!
description: String!
postedby: User
}
Prisma generates a GraphQL schema based on your datamodel. Doing so, it generates plural types based on your types.
However, because the plural of Species is Species, Prisma now has two types with the same name, therefore, throws an error. (See the same issue with News)
You currently can't choose the pluralized name for a type or field (See issue).
It's a generally good advice to only have singular names for your types.