Hi I’m very new to GraphQl. I’m trying to build an API with Apollo-server. I’m trying to create a user type with two different instances (normal client user type and a service provider user type). I created an interface user type, but I’m not exactly sure how to write mutation resolvers specific to subtypes of the interface user type. This is how my schema looks currently:
const {gql} = require('apollo-server-express')
module.exports = gql`
interface User{
id: ID!
username: String!
email: String!
password: String!
avatar: String!
bio: String!
# role: String!
}
type Order{
id: ID!
orderType: String!
author: User!
# paymentMethod: String!
}
type Stylist implements User{
id: ID!
username: String!
email: String!
password: String!
avatar: String!
bio: String!
# role: String!
rating: Int!
recievedOrders: [Order!]! #notification
recievedOrderCount: Int! #notification
}
type Client implements User{
id: ID!
username: String!
email: String!
password: String!
avatar: String!
bio: String!
# role: String!
sentOrders: [Order!]!
#acceptedorders
#rejectedOrders
#orderhistory
#purchases
}
type Query{
user(username: String!): User!
users: [User!]!
me: User!
# stylist(username: String): Stylist!
# stylists: [Stylist!]!
}
type Mutation{
makeOrder(orderType: String!): Order!
sendOrder(orderId: ID!, stylistId: ID!): Stylist!
updateSentOrders(id: ID!): User!
signUp(username: String!, email: String!, password: String!, role: String!): String!
signIn(username: String!, email: String!, password: String!): String!
}
`
Then is how my mutation resolver looks like currently:
const mongoose = require('mongoose')
const bcrypt = require('bcrypt')
const jwt = require('jsonwebtoken')
const {
AuthenticationError,
ForboddenError
} = require('apollo-server-express')
require('dotenv').config()
module.exports = {
//makeorder
makeOrder: async (parent, {orderType}, {models, user}) => {
if(!user){
throw AuthenticationError("Sorry you have to be signed in to make an order")
}
return await models.Order.create({
orderType,
author: mongoose.Types.ObjectId(user.id)
})
},
//sendOrder
sendOrder: async (parent, {orderId, stylistId}, {models, user}) => {
if(!user) {
throw AuthenticationError("Sorry you have to be signed in to make an order")
}
let order = await models.Order.findById(orderId)
//is this really needed?
if(order && String(order.author) !== user.id){
throw ForbiddenError("You don't have any permissions to make an order, please sign in")
}
return await models.Stylist.findOneAndUpdate(
{_id: stylistId},
{
$push: {
recievedOrders: mongoose.Types.ObjectId(orderId)
},
$inc: {
recievedOrderCount: 1
}
},
{
new: true
}
)
},
//updateSentOrders
updateSentOrders: async (parent, {id}, {models, user}) => {
if(!user) {
throw AuthenticationError("Sorry you have to be signed in")
}
let order = await models.Order.findById(id)
if(order && String(order.author) !== user.id) {
throw ForbiddenError("You don't have permissions to this order")
}
return await models.User.findOneAndUpdate(
{_id: user.id},
{
$push: {
sentORders: mongoose.Types.ObjectId(id)
}
},
{
new: true
}
)
},
signUp: async (parent, {username, email, password}, {models, user}) => {
var email = email.trim().toLowerCase()
var username = username
var saltrounds = 10
var encryptedPassword = await bcrupt.hash(password, saltRounds)
try{
const user = await model.User.create({
username,
email,
password: encryptedPassword
})
return await jwt.sign({id: user._id}, process.env.JWT_SECRET)
}catch(err) {
console.log(err)
throw new Error("error creating account")
}
},
signIn: async (parent, {username, email, password}, {models}) => {
if(email){
var email = email.trim().toLowerCase()
}
const user = await models.User.findOne({
$or: [{email}, {username}]
})
if(!user) {
throw new AuthenticationError('Error signing In')
}
const valid = await bcrypt.compare(password, user.password)
if(!valid) {
throw new AuthenticationError("Error signing In")
}
return await jwt.sign({id: user._id}, process.env.JWT_SECRET)
}
}
The part I’m really focused on is creating signups and signin for both instances of the User Interface type.
Help with this will be really great.