Variable value in graphql mutation isn't saving - graphql

I have simple mutation with variables as:
Mutation Query
mutation M($name: String) {
Adduser(name: $name) {
_id
name
}
}
Query variables
{
"name":"user1"
}
And in graphql API:
app.post('/graphql', (req, res) => {
const query = req.body.query;
const vars = req.body.variables;
//console.log(vars);/*showing { "name":"user1" }*/
graphql(Schema, query, null, vars).then(result => {
res.send(result);
});
});
but the output i am getting is:
{
"data": {
"Adduser": {
"_id": "593a2cd4cf057a07d073e971",
"name": null
}
}
}
Updated
userType:
const Adduser = {
type: userType,
args: {
name: {
type: graphql.GraphQLString
},
age: {
type: graphql.GraphQLInt
}
},
resolve: (obj, args) => {
return new Promise((resolve, reject) => {
var user=new User({
name:args.name
});
user.save(function(err,usr){
if(err){
console.log(err);
}
else{
resolve(usr);
}
});
})
}
};
mutation:
const Rootmutation = new graphql.GraphQLObjectType({
name: 'Rootmutation',
fields: {
Adduser: Adduser
}
});
const schema = new graphql.GraphQLSchema({
query: Rootquery,
mutation: Rootmutation
});
It means the variable value is not binding with mutation query.
Any suggestion here??

Related

GraphQL Array Error - "One of the provided types for building the Schema is missing a name"

I'm getting an error in my graphql resolvers file and it appears to be caused when I add the [ GraphQLID ]. Is this the correct way to add an array of GraphQLID's as I'm not entirely sure what I'm doing wrong.
const tvshowArgs = {
name: { type: GraphQLString },
composers: { type: [ GraphQLID ] },
}
const Mutation = {
addTvShow: {
type: TvShowType,
args: {
...tvshowArgs
},
resolve: async (parent, args, ctx) => {
const { user_id } = ctx.me
const doesExist = await TvShow.find({ tmdbId: args.tmdbId })
if (doesExist.length > 0) {
throw new GraphQLError('This TV Show already exists')
}
const tvshow = new TvShow({
name: args.name,
composers: args.composers,
})
return tvshow.save()
}
}
}

"Invalid URL: words" - apollo-server

I would like to create small project using GraphqQL, ApolloServer, but I encountered a problem, that I can't solve. I wrote it based on several documentation.
const { ApolloServer, gql } = require('apollo-server');
const { RESTDataSource } = require('apollo-datasource-rest');
const typeDefs = gql`
type Word {
id: ID!
word: String!
translation: String!
}
type Query {
words: [Word]
word(id: ID): Word
}
`;
class WordsAPI extends RESTDataSource {
constructor() {
super();
this.baseURL = 'localhost:5001/'
}
async getWord(id) {
return this.get(`word/${id}`)
}
async getAllWords() {
return this.get('words')
}
async getSpecifiedWords(SpecWord) {
return this.get(`words/${SpecWord}`)
}
}
const resolvers = {
Query: {
words: (_, __, { dataSources }) =>
dataSources.wordsAPI.getAllWords(),
word: async (_source, { id }, { dataSources }) => {
return dataSources.wordsAPI.getWord(id);
}
}
}
const server = new ApolloServer({
typeDefs,
resolvers,
dataSources: () => {
return {
wordsAPI: new WordsAPI()
};
},
context: () => {
return {
};
},
});
server.listen().then(({ url }) => {
console.log(`🚀 Server ready at ${url}`);
});
After
query {
words {
translation
}
}
In playground I am getting Invalid URL: words.
At localhost:5001/words is database and in Postman it works.
What did I bad?

How to use remove mutation in Relay server?

I work with an express graphql server, prepared for react-relay.
Queries and createPost mutation works correctly in graphiql interface.
There is a problem with removePost mutation.
Trying to use it, I get this responce:
"Cast to ObjectId failed for value \"{ id: '5db0026a76376e0f7c82d431'
}\" at path \"_id\" for model \"Post\".
Tell me please, what's wrong with removePost mutation. Thanks!
Post.js:
const mongoose = require('mongoose');
mongoose.Promise = global.Promise;
mongoose.connect("mongodb://localhost/relay-project", {
useNewUrlParser: true,
useUnifiedTopology: true
});
const Schema = mongoose.Schema;
const postSchema = new Schema({
title: String,
content: String
});
var PostModel = mongoose.model("Post", postSchema);
module.exports = {
getPosts: () => {
return PostModel.find().sort({_id: -1});
},
getPost: id => {
return PostModel.findOne({ _id: id });
},
createPost: post => {
return PostModel(post).save();
},
removePost: id => {
return PostModel.findByIdAndRemove(id);
}
};
Mutation.js:
const {
GraphQLObjectType,
GraphQLNonNull,
GraphQLString,
GraphQLID
} = require('graphql');
const {mutationWithClientMutationId} = require('graphql-relay');
const {Post} = require('./Post');
const PostModel = require('../model/Post');
const CreatePostMutation = mutationWithClientMutationId({
name: "CreatePost",
inputFields: {
title: {type: new GraphQLNonNull(GraphQLString)},
content: {type: new GraphQLNonNull(GraphQLString)}
},
outputFields: {
post: {
type: Post
}
},
mutateAndGetPayload: args => {
return new Promise((resolve,reject)=>{
PostModel.createPost({
title: args.title,
content: args.content
})
.then(post=>resolve({post}))
.catch(reject);
});
}
});
const RemovePostMutation = mutationWithClientMutationId({
name: "RemovePost",
inputFields: {
id: {type: GraphQLID}
},
outputFields: {
post: {
type: Post
}
},
mutateAndGetPayload: args => {
return new Promise((resolve,reject)=>{
PostModel.removePost({
id: args.id
})
.then(post=>resolve({post}))
.catch(reject);
});
}
});
const Mutation = new GraphQLObjectType({
name: "Mutation",
description: "kjhkjhkjhkjh",
fields: {
createPost: CreatePostMutation,
removePost: RemovePostMutation
}
});
module.exports = Mutation;
you have to convert your id to object id as mongodb save
i guess use below code for id
const toBase64 = (str: string) => {
return new Buffer(str.toString()).toString('base64')
}
const fromBase64 = (str: string) => {
return Buffer.from(str, 'base64').toString('ascii')
}
The working mutation is:
const RemovePostMutation = mutationWithClientMutationId({
name: "RemovePost",
inputFields: {
id: { type: new GraphQLNonNull(GraphQLString) },
},
outputFields: {
deleted: { type: GraphQLBoolean },
deletedId: { type: GraphQLString }
},
mutateAndGetPayload: async ({ id }, { viewer }) =>{
const { id: productId } = fromGlobalId(id);
const result = await PostModel.removePost(productId);
return { deletedId: id, deleted: true };
}
});
Cheers, Kiten

graphql-subscriptions withFilter returns undefined; subscriptions without variables work ok

I'm trying to get my head around graphql-subscriptions and withFilter. Subscriptions without variables work as intended, but if I try to use withFilter, I only get 'Subscription field must return Async Iterable. Received: undefined' error when I try to run the subscription.
Am I doing something wrong with setting up withFilter, are the some incompatibilities with packages I'm using or am I completely missing something obvious here? All queries and mutations work properly, so the basic set up should be fine.
My set up is similar to this (all code snippets are in https://gist.github.com/aqmattil/41e10e7c9f30b8ea964cecdc61c58f20
Package.json
// package.json
"dependencies": {
"apollo-server-express": "^2.0.0-beta.2",
"body-parser": "^1.18.3",
"express": "^4.16.3",
"graphql": "^0.13.2",
"graphql-subscriptions": "^0.5.8",
"subscriptions-transport-ws": "^0.9.11"
}
Mutations
// mutations.js
const mutation = new GraphQLObjectType({
name: 'mutation',
fields: {
addSite: {
type: SiteType,
description: "Create a new Site",
args: {
name: { type: new GraphQLNonNull(GraphQLString) },
location: { type: GraphQLString },
company: { type: GraphQLString }
},
async resolve(parentValue, { name, location, company }) {
const site = await new Site({ name, location, company }).save()
const siteid = site._id;
console.log("addSite resolve", siteid, name, location, company );
pubsub.publish('siteAdded', { 'siteAdded': site } );
return site;
}
}
}
});
module.exports = mutation;
Subscriptions
// subscriptions.js
const graphql = require('graphql');
const {
GraphQLObjectType,
GraphQLString
} = graphql;
const { withFilter } = require('graphql-subscriptions');
const SiteType = require('./site_type');
const pubsub = require('./pubsub_helper');
const Subscriptions = new GraphQLObjectType({
name: 'subscription',
fields: () => ({
/*
// this code works, commented out to test withfilter
siteAdded: {
type: SiteType,
resolve(payload) {
return payload.siteAdded;
},
subscribe() {
return pubsub.asyncIterator('siteAdded');
}
},
*/
// test withFilter
siteAdded: {
type: SiteType,
args: {
name: { type: GraphQLString }
},
resolve(payload) {
return payload.siteAdded;
},
subscribe() {
// this returns undefined
withFilter(
() => {
console.log("in subscribe withfilter");
return pubsub.asyncIterator('siteAdded');
}
),
(payload, variables) => {
console.log("payload, variables", payload, variables);
return true;
}
}
}
})
});
module.exports = Subscriptions;
I'm using graphiql to run the queries,
// this is used to add a site
mutation {
addSite(name:"test name", location: "somewhere") {
id
}
}
// simple subscription - this works as inteded, and new sites are shown
subscription {
siteAdded {
name
location
company {
id
}
}
}
// using query variables --> returns "Subscription
// field must return Async Iterable. Received: undefined"
subscription {
siteAdded(name: "test name") {
name
location
company {
id
}
}
}

How do you define multiple query or mutation in GraphQLSchema

I am new to GraphQL. Forgive me if this is obvious.
Beside using buildSchema, is there a way to define more than one query/mutation using new GraphQLSchema?
This is what I have right now.
const schema = new graphql.GraphQLSchema(
{
query: new graphql.GraphQLObjectType({
name: 'RootQueryType',
fields: {
count: {
type: graphql.GraphQLInt,
resolve: function () {
return count;
}
}
}
}),
mutation: new graphql.GraphQLObjectType({
name: 'RootMutationType',
fields: {
updateCount: {
type: graphql.GraphQLInt,
description: 'Updates the count',
resolve: function () {
count += 1;
return count;
}
}
}
})
});
Multiple "queries" are actually just multiple fields on one Query type. So just add more fields to that GraphQLObjectType, like so:
query: new graphql.GraphQLObjectType({
name: 'RootQueryType',
fields: {
count: {
type: graphql.GraphQLInt,
resolve: function () {
return count;
}
},
myNewField: {
type: graphql.String,
resolve: function () {
return 'Hello world!';
}
}
}
}),

Resources