问题
I have a schema as follows:
type Artist @model {
id: ID! @isUnique
createdAt: DateTime!
updatedAt: DateTime!
name: String! @isUnique
songkickId: String
shows: [Show!]! @relation(name: "ArtistShow")
}
type Show @model {
id: ID! @isUnique
createdAt: DateTime!
updatedAt: DateTime!
name: String
songkickId: String
date: DateTime!
soldOut: Boolean!
pit: Boolean!
ages: String!
price: String!
multiDay: Boolean!
artists: [Artist!]! @relation(name: "ArtistShow")
venue: Venue! @relation(name: "ShowVenue")
}
type Venue @model {
id: ID! @isUnique
createdAt: DateTime!
updatedAt: DateTime!
name: String! @isUnique
address: String
latitude: Float
longitude: Float
metro: String
songkickId: String @isUnique
shows: [Show!]! @relation(name: "ShowVenue")
}
I have written mutations that, given JSON data, create Artists and Venues and return those to me.
At the time that I want to create a Show, I have:
- An array of
ArtistIDs - An ID for a
Venue - All required info to populate the rest of the
Showdata (in an object calledshowInfo)
I have a mutation that looks like this:
mutation: gql`
mutation {
createShow(
date: "${showInfo.date}"
soldOut: ${showInfo.soldOut}
pit: ${showInfo.pit}
ages: "${showInfo.ages}"
price: "${showInfo.price}"
multiDay: ${showInfo.multiDay}
) {
id
}
}
`,
How do I edit this so that I also create relations between a Show that I am creating and appropriate Venue and Artist IDs?
回答1:
I had to structure the JSON so that I had access to a list of Artists and a Venue at the time that I was writing a Show.
I then had to write each Artist and Venue (or validate whether these had already been written) to graphcool and get a respective ID back.
I then executed a function like the following:
async findShowOrCreate (showInfo, artists, venue) {
const tempDate = new Date(showInfo.date);
this.logger.info(`BEGIN : write show to graphcool (${showInfo.venue} on ${tempDate.toDateString()})`);
const showQuery = `
query ($venueId: ID!, $date: DateTime) {
allShows(filter: {
venue: {
id: $venueId
}
date: $date
}) {
id
}
}
`
const existentialShowTest = await this.client.request(showQuery,
{venueId: venue, date: showInfo.date})
if (existentialShowTest.allShows.length < 1){
const addShowQuery = `
mutation createShow($artistsIds:[ID!], $venueId:ID ) {
createShow (
artistsIds: $artistsIds
venueId: $venueId
date: "${showInfo.date}"
soldOut: ${showInfo.soldOut}
pit: ${showInfo.pit}
ages: "${showInfo.ages}"
price: "${showInfo.price}"
multiDay: ${showInfo.multiDay}
) {
id
}
}
`
const finalResult = await this.client.request(addShowQuery,
{venueId: venue, artistsIds: artists})
.then(data => {
const result = data.createShow.id
this.logger.info(`FINISH: write show to graphcool as ${result}`)
return result
})
.catch(error => this.logger.error(error));
return finalResult
} else {
this.logger.info(`FINISH: found show in graphcool`)
return existentialShowTest.allShows[0]
}
}
which first ran a query to make sure that a Show representing the union of a specific date and Venue didn't already exist in graphcool, then ran a mutation to add a Show.
Note that this mutation was specifically structured to take in Ids for existing Venue and Artist objects (the latter in list form) and to attach these as variables in the line:
client.request(addShowQuery,
{venueId: venue, artistsIds: artists})
using the graphql-request library, which allows you to pass a hash of variables into requests to graphcool.
来源:https://stackoverflow.com/questions/48597470/graphql-graphcool-how-to-write-a-mutation-that-links-both-a-oneone-and-a-onem