400 对 GraphQL 端点的错误请求(我的测试查询有什么问题?)
400 Bad Requst to GraphQL endpoint (What's wrong with my test's query?)
我主要关注关于 how to create a mutation 的 GraphQL 文档。这是我第一天使用 GraphQL。我想为评论创建一个端点。
隔离问题
我从我的 supertest
在摩卡回来 400 "Bad Request" 当我尝试 运行 GraphiQL 时它给了我错误数组中的一条消息说,"Query root type must be provided." ...但我 am 包括 rootValue
.
问题可能出在 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
});
这会被导入,然后在 express 服务器的顶层使用,comments
像这样:
app.use("/comments", comments);
工作原理: GraphiQL 会在浏览器的 localhost:8080/comments
处弹出,所以我很确定快递方面没有问题。 (顺便说一句,TypeScript 编译得很好。)我还有一个不同的 GraphQL api 端点 returns,"Hello world!" 在我正在使用 Mocha 测试的服务器的顶层,它通过(在最初失败之后),所以我的测试套件似乎运行良好。没有额外的环境变量。这就是您在这里看到的。
我想通过的测试给出了 404 错误请求:
// 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();
});
});
});
既然写着"bad request",我在测试中处理query
和variables
的方式肯定是问题所在。
问题
我的问题是测试中的查询和变量还是我的buildSchema
? ...还是两者兼而有之?我将如何以不同的方式编写以使测试通过?
更新
在我注释掉导出中的 rootValue 之后,就像这样,因为它说 GraphiQL 中的 "Query root type must be provided," 我发现没有区别。就好像 rootValue
不存在,即使它存在。
export default graphqlHTTP({
graphiql: true,
// rootValue: root,
schema
});
一旦我根据 this Github issue 中提到的内容添加了 Query
和 getComment()
,GraphiQL 中的错误消息就消失了。不幸的是,测试仍然给出 400 Bad Request 所以问题似乎无关。
更新 2
我用 GraphiQL 测试了我的端点,当我 post 使用:
时,它起到了 expected/desired 的作用
mutation {
createOrUpdateComment(input: {_id: "4", author: "Some Author", text: "some unique text"}) {
_id
author
text
}
}
我正在努力使我的测试查询相似,但它们不是类似物。这清楚地表明问题出在测试本身,当我记录主体的响应时,我得到了这个:
所以我的测试查询字符串有问题。
已解决。
请参阅下面的回答。
GraphQL 中有三种操作——查询、变更和订阅。每个操作都有一个与之关联的对象类型。这些称为 根类型 。默认情况下,这些根类型分别命名为 Query
、Mutation
和 Subscription
(这些名称无关紧要,可以根据您的特定模式进行更改,但这些是默认值)。根类型作为入口点,或 root,到您的架构的其余部分,以针对它进行任何查询。
规范要求查询根类型,而其他两种根类型是可选的,可以省略。
该错误与 根值 无关。事实上,你可能 。如错误所示,您没有在架构中提供查询根类型。您的架构包含的唯一根类型是 Mutation
。您需要添加 Query
才能解决错误。
我在测试中的主要问题是
- 我是JSON.stringifying数据。那是在文档的 example using fetch 中,但 supertest 会自动将数据转换为 JSON 字符串。
- 我将我的查询调整为只有一个字符串,没有添加任何变量。我想尽快尝试一下,看看是否可以用变量发送它,但我只是想简化事情。
- 根据 Daniel Rearden 的建议,我注销了正文。这是一条无价的调试建议,我没想过在测试中这样做,因为我只是假设,"Well, it's erroring out, right?" Duh。没有。总会有回应的。这帮助我直接设置 return 值。
这是我最终得到的测试文件:
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();
});
});
});
我主要关注关于 how to create a mutation 的 GraphQL 文档。这是我第一天使用 GraphQL。我想为评论创建一个端点。
隔离问题
我从我的 supertest
在摩卡回来 400 "Bad Request" 当我尝试 运行 GraphiQL 时它给了我错误数组中的一条消息说,"Query root type must be provided." ...但我 am 包括 rootValue
.
问题可能出在 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
});
这会被导入,然后在 express 服务器的顶层使用,comments
像这样:
app.use("/comments", comments);
工作原理: GraphiQL 会在浏览器的 localhost:8080/comments
处弹出,所以我很确定快递方面没有问题。 (顺便说一句,TypeScript 编译得很好。)我还有一个不同的 GraphQL api 端点 returns,"Hello world!" 在我正在使用 Mocha 测试的服务器的顶层,它通过(在最初失败之后),所以我的测试套件似乎运行良好。没有额外的环境变量。这就是您在这里看到的。
我想通过的测试给出了 404 错误请求:
// 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();
});
});
});
既然写着"bad request",我在测试中处理query
和variables
的方式肯定是问题所在。
问题
我的问题是测试中的查询和变量还是我的buildSchema
? ...还是两者兼而有之?我将如何以不同的方式编写以使测试通过?
更新
在我注释掉导出中的 rootValue 之后,就像这样,因为它说 GraphiQL 中的 "Query root type must be provided," 我发现没有区别。就好像 rootValue
不存在,即使它存在。
export default graphqlHTTP({
graphiql: true,
// rootValue: root,
schema
});
一旦我根据 this Github issue 中提到的内容添加了 Query
和 getComment()
,GraphiQL 中的错误消息就消失了。不幸的是,测试仍然给出 400 Bad Request 所以问题似乎无关。
更新 2
我用 GraphiQL 测试了我的端点,当我 post 使用:
时,它起到了 expected/desired 的作用mutation {
createOrUpdateComment(input: {_id: "4", author: "Some Author", text: "some unique text"}) {
_id
author
text
}
}
我正在努力使我的测试查询相似,但它们不是类似物。这清楚地表明问题出在测试本身,当我记录主体的响应时,我得到了这个:
所以我的测试查询字符串有问题。
已解决。
请参阅下面的回答。
GraphQL 中有三种操作——查询、变更和订阅。每个操作都有一个与之关联的对象类型。这些称为 根类型 。默认情况下,这些根类型分别命名为 Query
、Mutation
和 Subscription
(这些名称无关紧要,可以根据您的特定模式进行更改,但这些是默认值)。根类型作为入口点,或 root,到您的架构的其余部分,以针对它进行任何查询。
规范要求查询根类型,而其他两种根类型是可选的,可以省略。
该错误与 根值 无关。事实上,你可能 Mutation
。您需要添加 Query
才能解决错误。
我在测试中的主要问题是
- 我是JSON.stringifying数据。那是在文档的 example using fetch 中,但 supertest 会自动将数据转换为 JSON 字符串。
- 我将我的查询调整为只有一个字符串,没有添加任何变量。我想尽快尝试一下,看看是否可以用变量发送它,但我只是想简化事情。
- 根据 Daniel Rearden 的建议,我注销了正文。这是一条无价的调试建议,我没想过在测试中这样做,因为我只是假设,"Well, it's erroring out, right?" Duh。没有。总会有回应的。这帮助我直接设置 return 值。
这是我最终得到的测试文件:
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();
});
});
});