问题
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 Artist
s and Venue
s and return those to me.
At the time that I want to create a Show
, I have:
- An array of
Artist
IDs - An ID for a
Venue
- All required info to populate the rest of the
Show
data (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 Artist
s 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