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.
Isolating the problem
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.
The Question
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?
Update
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.
Update 2
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.
Solved.
See my answer below.