hez
06/11/2018, 4:51 PMhez
06/11/2018, 4:52 PMimport { helmet } from '../core/utils/helmet'
import { getVehicle, newVehicle, updateVehicle } from './resolvers'
export default {
Query: {
getVehicle: helmet(getVehicle),
},
Mutation: {
newVehicle: helmet(newVehicle),
updateVehicle: helmet(updateVehicle),
},
Vehicle: {
driver: async ( { userID }, args, context, info) => {
return context.db.query.driverProfile({ where: { userID } }, info)
},
},
}
hez
06/11/2018, 4:53 PMimport { Token } from '../../core/classes' // [TO DO]: get rid of the pathing
export const updateVehicle = async (obj, args, context, info) => {
try {
const token = new Token(context.request.headers.authorization)
await token.validate()
return await context.db.mutation.updateVehicle({
where: { vehicleID: args.vehicle.vehicleID },
// data: args.vehicle },
data: {
driver: {
connect: {
userID: args.vehicle.driver.userID,
},
},
},
info,
})
} catch (error) {
return error
}
}
hez
06/11/2018, 4:53 PMQuery
with a custom type resolver for driver
hez
06/11/2018, 4:54 PMhez
06/11/2018, 4:55 PMVehicle.driver
resolver, userID
comes back as null
, because the parent object coming through is the Vehicle
which has no userID
hez
06/11/2018, 4:55 PMhez
06/11/2018, 4:55 PMhez
06/11/2018, 4:55 PMlawjolla
06/11/2018, 4:56 PMlawjolla
06/11/2018, 4:56 PMhez
06/11/2018, 4:56 PMmutation {
updateVehicle( vehicle: {
vehicleID: "1",
driver: {
userID: "5af31686a6803a91913d42e6"
}
}) {
vehicleID
driver {
userID
}
}
}
hez
06/11/2018, 4:57 PMhez
06/11/2018, 4:57 PMVehicle
and request driver infohez
06/11/2018, 4:58 PMhez
06/11/2018, 4:58 PMVehicle: {
driver: async ( { userID }, args, context, info) => {
return context.db.query.driverProfile({ where: { userID } }, info)
},
},
hez
06/11/2018, 4:58 PMhez
06/11/2018, 4:58 PMuserID
is null
)lawjolla
06/11/2018, 4:59 PMlawjolla
06/11/2018, 5:00 PMVehicle: {
driver: {
fragment: `fragment getUserId on Vehicle { userID } `,
resolve: async ( { userID }, args, context, info) => {
return context.db.query.driverProfile({ where: { userID } }, info)
},
},
lawjolla
06/11/2018, 5:01 PMextractFragmentReplacements
from prisma-binding
lawjolla
06/11/2018, 5:03 PMresolvers/index
and then I pass fragmentReplacements
into the Prisma constructor.
const { extractFragmentReplacements } = require(`prisma-binding`)
const { fileLoader } = require("merge-graphql-schemas")
const path = require("path")
const resolvers = fileLoader(path.join(__dirname, "../entity/**/resolver.js"))
const fragmentReplacements = extractFragmentReplacements(resolvers)
module.exports = { resolvers, fragmentReplacements }
hez
06/11/2018, 5:06 PMVehicle
type doesn't have a userID
-- just the driver which is associated with Vehicle
hez
06/11/2018, 5:08 PMlawjolla
06/11/2018, 5:09 PMfragment getUserId on Vehicle { driver { userID } }
. You may be able to fragment: fragment getUserId on Driver { userID }
but I'm not as fresh on my fragments as I should be 🙂hez
06/11/2018, 5:10 PMhez
06/11/2018, 5:10 PMlawjolla
06/11/2018, 5:10 PMhez
06/11/2018, 5:39 PMVehicle: {
driver: {
fragment: `fragment getUserID on Vehicle { driver { userID } }`,
resolve: async ( { userID }, args, context, info) => {
console.log('>>>>>>>>>>>>>>>>> ', info)
// context.db.query.driverProfile({ where: { userID } }, info)
},
},
},
It still fails, and info.fragments
shows as an empty objecthez
06/11/2018, 5:40 PMconst server = new GraphQLServer({
schema,
context: (req) => ({
...req,
db: new Prisma({
fragmentReplacements,
typeDefs: 'generated/prisma.graphql',
endpoint: process.env.PRISMA_ENDPOINT,
secret: process.env.MANAGEMENT_API_SECRET,
debug: true,
}),
}),
})
hez
06/11/2018, 5:43 PMfragmentReplacements
just before instantiating Prisma, I get something useful:
FRAGMENT REPLACEMENTS: { Vehicle:
{ driver:
{ kind: 'InlineFragment',
typeCondition: [Object],
selectionSet: [Object] } } }
hez
06/11/2018, 5:51 PMhez
06/11/2018, 5:57 PMhez
06/11/2018, 5:57 PMhez
06/11/2018, 6:28 PMError: Variable "$_where" got invalid value {"currentVehicle":{"id":"cjiabbu18000z0922p2j2soay"}}; Field "currentVehicle" is not defined by type DriverProfileWhereUniqueInput.
hez
06/11/2018, 6:28 PMVehicle: {
driver: {
fragment: `fragment VehicleID on Vehicle { id }`,
resolve: async ( { id }, args, context, info) => {
return context.db.query.driverProfile({ where: { currentVehicle: { id } } })
},
},
},
hez
06/11/2018, 6:29 PMinfo.fragments
, and id
exists on the parent object being passed to the resolverhez
06/11/2018, 6:29 PMlawjolla
06/11/2018, 6:36 PMid
isn't coming back suggests there's a problem with the fragment parsing codelawjolla
06/11/2018, 6:37 PMVehicle
query and see if id
returns. If it doesn't, that's likely the issuehez
06/11/2018, 6:41 PMlawjolla
06/11/2018, 6:41 PMhez
06/11/2018, 6:41 PMdiverProfiles
but not driverProfile
because it is not seeing the currentVehicle
as uniquehez
06/11/2018, 6:41 PMhez
06/11/2018, 6:41 PMlawjolla
06/11/2018, 6:42 PMQuery.driverProfile
?hez
06/11/2018, 6:43 PMtype DriverProfile {
id: ID! @unique
userID: String! @unique
currentVehicle: Vehicle
}
type Vehicle {
id: ID! @unique
vehicleID: String! @unique
driver: DriverProfile
}
hez
06/11/2018, 6:44 PMdriverProfile
using a vehicle ID is that it's not unique.hez
06/11/2018, 6:44 PMdriverProfiles
I get an array with a single memberhez
06/11/2018, 6:45 PM@unique
?lawjolla
06/11/2018, 6:45 PMhez
06/11/2018, 6:46 PMlawjolla
06/11/2018, 6:49 PMDriverProfile
with userID and Vehicle
with vehicleId
separately, right?hez
06/11/2018, 6:50 PMlawjolla
06/11/2018, 6:50 PMhez
06/11/2018, 6:51 PMhez
06/11/2018, 6:51 PMlawjolla
06/11/2018, 6:52 PMhez
06/11/2018, 6:54 PMhez
06/11/2018, 6:54 PMhez
06/11/2018, 6:55 PMhez
06/11/2018, 6:56 PMhez
06/11/2018, 6:57 PMlawjolla
06/11/2018, 6:57 PMhez
06/11/2018, 6:58 PMhez
06/11/2018, 6:58 PMhez
06/11/2018, 6:58 PMlawjolla
06/11/2018, 7:00 PMhez
06/11/2018, 7:01 PMhez
06/11/2018, 7:01 PMlawjolla
06/11/2018, 7:01 PMhez
06/11/2018, 7:01 PMlawjolla
06/11/2018, 7:02 PMlawjolla
06/11/2018, 7:06 PMlawjolla
06/11/2018, 7:07 PMlawjolla
06/11/2018, 7:08 PMquery {
Vehicle(where: { id: "a stored vehicle id"}) {
driver { id }
}
}
returns what?hez
06/11/2018, 7:10 PMnull
, if I recall... but it's been a minute. confirming nowhez
06/11/2018, 7:13 PMquery {
getVehicle (vehicleID: "1") {
vehicleID
make
model
driver {
userID
}
}
}
Returns the following:
{
"data": {
"getVehicle": null
},
"errors": [
{
"message": "Cannot read property 'userID' of undefined",
"locations": [
{
"line": 2,
"column": 3
}
],
"path": [
"getVehicle"
]
}
]
}
lawjolla
06/11/2018, 7:13 PMhez
06/11/2018, 7:13 PMexport const getVehicle = async (obj, args, context, info) => {
try {
const token = new Token(context.request.headers.authorization)
await token.validate()
return await context.db.query.vehicle(
{
where: args,
data: {
driver: {
connect: {
userID: args.driver.userID,
},
},
},
},
info,
)
} catch (error) {
return error
}
}
hez
06/11/2018, 7:14 PMhez
06/11/2018, 7:16 PMcannot query field 'id' on type 'DriverProfile'
lawjolla
06/11/2018, 7:19 PMdata
under db.query
because that's a query.mutation
propertylawjolla
06/11/2018, 7:21 PMreturn await context.db.query.vehicle(
{
where: { id: args.id },
info
)
hez
06/11/2018, 7:26 PMexport default {
Query: {
getVehicle: async (obj, args, context, info) => {
try {
const token = new Token(context.request.headers.authorization)
await token.validate()
return await context.db.query.vehicle({ where: args }, info)
} catch (error) {
return error
}
},
},
Vehicle: {
driver: {
fragment: `fragment getUserID on DriverProfile { id }`,
resolve: async ( { id }, args, context, info) => {
return context.db.query.driverProfiles({ where: { id } })
},
},
},
}
hez
06/11/2018, 7:26 PM{
"data": {
"getVehicle": {
"vehicleID": "1",
"driver": {
"userID": null
}
}
}
}
lawjolla
06/11/2018, 7:28 PMhez
06/11/2018, 7:29 PMhez
06/11/2018, 7:30 PMhez
06/11/2018, 7:30 PMlawjolla
06/11/2018, 7:30 PMlawjolla
06/11/2018, 7:30 PMhez
06/11/2018, 7:31 PMhez
06/11/2018, 7:31 PMhez
06/11/2018, 7:31 PMlawjolla
06/11/2018, 7:31 PMhez
06/11/2018, 7:32 PMlawjolla
06/11/2018, 7:32 PMinfo
object?hez
06/11/2018, 7:32 PMlawjolla
06/11/2018, 7:34 PMhez
06/11/2018, 7:34 PMlawjolla
06/11/2018, 7:34 PMhez
06/11/2018, 8:04 PMconnect
?lawjolla
06/11/2018, 8:04 PMlawjolla
06/11/2018, 8:05 PMmutation {
connectDriverAndVehicle(...): Vehicle
}
hez
06/11/2018, 8:05 PMupdateVehicle
mutation?hez
06/11/2018, 8:06 PMhez
06/11/2018, 8:06 PMlawjolla
06/11/2018, 8:11 PMupdateVehicle
type. My personal opinion is if others aren't consuming your API (i.e. just your client), the generic may be useful as a time saver. Otherwise, I'd make it specifichez
06/11/2018, 8:12 PMhez
06/11/2018, 8:12 PMlawjolla
06/11/2018, 8:12 PMlawjolla
06/11/2018, 8:12 PMnilan
06/12/2018, 12:17 PM