Reputation: 2761
I am largely following the GraphQL documentation about how to create a mutation. This is my first day working with GraphQL. I want to create an endpoint for comments.
I'm getting back 400 "Bad Request" from my supertest
in Mocha and when I try to run the GraphiQL it gives me a message in an errors array that says, "Query root type must be provided." ...But I am including rootValue
.
One place the problem could be is in the buildSchema
.
// imports (...working fine)
// Comment Interface for TypeScript is here ...and working
// ...
// gaphql schema (The problem could be here.)
const schema = buildSchema(`
input CommentInput {
_id: String
author: String
text: String
}
type Comment {
_id: String
author: String
text: String
}
type Mutation {
createOrUpdateComment(input: CommentInput): Comment
}
`);
// rootValue
const root = {
createOrUpdateComment: ({input}: { input: IComment }) => {
return {
_id: "id here",
author: input.author,
text: input.text
}
}
};
export default graphqlHTTP({
graphiql: true,
rootValue: root,
schema
});
This gets imported and then used in the top level of the express server, as comments
like so:
app.use("/comments", comments);
What's working: The GraphiQL does pop up at localhost:8080/comments
in the browser, so I'm pretty sure there's no issues on the Express side of things. (TypeScript compiles just fine, by the way.) I also have a different GraphQL api endpoint that returns, "Hello world!" on the top level of the server that I am testing using Mocha and it passes (after it initially failed), so my testing suite seems to be working well. There are no additional environmental variables. It's just what you see here.
The test that I want to pass, which gives me the 404 bad request is:
// imports (...working fine)
describe("graphQl comments test", () => {
it("should add a comment", (done) => {
const query = `mutation createOrUpdateComment($input: CommentInput) {
_id
author
text
}`;
const variables = {
input: {
author: "Brian",
text: "This is my favorite video of all time."
}
};
request(app)
.post("/comments")
.send(JSON.stringify({ query, variables})) // (The problem could be here.)
.expect(200)
.end((err, res) => {
if (err) { return done(err); }
// tslint:disable-next-line: no-unused-expression
expect(res.body.data.id).to.exist;
expect(res.body.data.author).to.equal("Brian");
expect(res.body.data.text).to.equal("This is my favorite video of all time.");
done();
});
});
});
Since it says "bad request", the way I handle the query
and the variables
in the test definitely could be the problem.
Is my problem the query and variables in the test or is it my buildSchema
? ...Or is it both? How would I write either differently to get the test to pass?
After I commented out the rootValue in the exports, like so, since it was saying, "Query root type must be provided," in GraphiQL I found there is no difference. It's as if the rootValue
isn't there, even though it is.
export default graphqlHTTP({
graphiql: true,
// rootValue: root,
schema
});
Once I added a Query
and a getComment()
per something mentioned in this Github issue the error message in GraphiQL is gone. The test, unfortunately, is still giving 400 Bad Request so the problems seem to be unrelated.
I tested my endpoint out with GraphiQL and it functioned as expected/desired, when I post with:
mutation {
createOrUpdateComment(input: {_id: "4", author: "Some Author", text: "some unique text"}) {
_id
author
text
}
}
I'm working on making my tests query similar, but they're not analogues. This makes it clear that the problem is in the test itself and when I log the body's response I get this:
So there's something wrong with my test's query string.
See my answer below.
Upvotes: 1
Views: 2520
Reputation: 2761
My main problems in the test was that
This is the test file I ended up with:
import { expect } from "chai";
import request = require("supertest");
import app from "../src";
describe("graphQl comments test", () => {
it("should add a comment", (done) => {
const query = `mutation {
createOrUpdateComment(input: {_id: "4", author: "Brian", text: "This is my favorite video of all time."}) {
_id
author
text
}
}`;
request(app)
.post("/comments")
.send({query})
.expect(200)
.end((err, res) => {
if (err) { return done(err); }
// tslint:disable-next-line: no-unused-expression
expect(res.body.data.createOrUpdateComment._id).to.exist;
expect(res.body.data.createOrUpdateComment.author).to.equal("Brian");
expect(res.body.data.createOrUpdateComment.text).to.equal("This is my favorite video of all time.");
done();
});
});
});
Upvotes: 0
Reputation: 84687
There are three operations in GraphQL -- queries, mutations and subscriptions. Each operation has a single object type associated with it. These are called root types. These root types are by default named, respectively, Query
, Mutation
and Subscription
(the names are irrelevant and can be changed for your specific schema, but these are the defaults). The root types serve as the entry point, or root, to the rest of your schema for any query made against it.
The query root type is required by the specification, while the other two root types are optional and may be omitted.
The error is not related to the root value whatsoever. In fact, you probably shouldn't be using buildSchema and rootValue in the first place. As the error indicates, you have not provided a query root type in your schema. The only root type your schema includes is Mutation
. You need to add Query
in order to resolve the error.
Upvotes: 1