我是不是错误地使用了 GraphQL?我不知道它是如何向我发回数据的

Posted

技术标签:

【中文标题】我是不是错误地使用了 GraphQL?我不知道它是如何向我发回数据的【英文标题】:Am I using GraphQL incorrectly? I don't know how it sends me back data我是否错误地使用了 GraphQL?我不知道它是如何向我发回数据的 【发布时间】:2018-02-12 03:06:36 【问题描述】:

所以我正在做一个项目,希望我使用 GraphQL 来创建我的 API。我也在使用 NodeJS 和 Express。通常我只是在 express 中设置一个端点,然后从客户端用 axios 调用它。在服务器上的端点内部,我可以从 req.body 获取信息并按照我的意愿使用它。我可以在哪里使用 GraphQL 以同样的方式操作数据?感觉就像我所做的只是查询数据,而不是像我想要的那样操作并发送回去。

这是我所拥有的:

Schema graphql:

import GraphQLDate from 'graphql-date';

const 
  GraphQLObjectType,
  GraphQLString,
  GraphQLInt,
  GraphQLSchema,
  GraphQLList,
  GraphQLNonNull,
 = require('graphql');


const SecretMessage = new GraphQLObjectType(
  name: 'secretMessage',
  fields: () => (
    id:  type: GraphQLString ,
    name:  type: GraphQLString ,
    message:  type: GraphQLString ,
    expirDate:  type: GraphQLDate ,
  ),
);

const RootQuery = new GraphQLObjectType(
  name: 'RootQueryType',
  fields: 
    secretMessage: 
      type: SecretMessage,
      args: 
        name:  type: GraphQLString ,
      ,
      resolve(parVal, args) 
        return `$args.nametest`;
      ,
    ,
  ,
);

module.exports = new GraphQLSchema(
  query: RootQuery,
);

我的节点服务器:

import express from 'express';
import path from 'path';
import bodyParser from 'body-parser';
import webpack from 'webpack';

const config = require('../webpack.config.js');
const expressGraphQL = require('express-graphql');
const schema = require('./schema.js');


const compiler = webpack(config);
const port = process.env.PORT || 3000;

const app = express();


app.use(bodyParser.json());
app.use(bodyParser.urlencoded( extended: true ));

app.use(express.static('public'));
app.use(express.static('css'));
app.use(express.static('images'));

app.use('/graphql', expressGraphQL(
  schema,
  graphiql: true,
));

app.get('/', (req, res) => 
  res.sendFile(path.join(__dirname, '../public/src', 'index.html'));
);

app.get('#', (req, res) => 
  console.log('Pound hashtag works');
);

app.post('passphrase', (req, res) => 
  console.log('passphrase tag works');
);

app.get('*', (req, res) => 
  res.sendFile(path.join(__dirname, '../public/src', 'index.html'));
);

app.listen(port, (error) => 
  if (error) 
    console.log('This is the express error: ', error);
   else 
    console.log('Express is listening on port: ', port);
  
);

    axios(
      method: 'post',
      url: '/graphql',
      data: JSON.stringify(
        query: `secretMessage(name: "$this.state.name") name`,
      ),
    ).then((response) => 
      console.log('This is the response from the axios call: ', response);
    ).catch((error) => 
      console.log('This is the error from the main axios call: ', error);
    );

当我对 /graphql 进行 axios 发布调用时,我只收到 400 bad request 错误。

字符串插值旁边的“测试”是我只是想看看我是否可以操纵那里的数据。我不知道如何在邮递员中测试它。有什么想法吗?

【问题讨论】:

【参考方案1】:

假设您使用 express-graphql 或类似的中间件,您的 GraphQL 端点将可以使用 POST 和 GET 请求访问。

使用 POST:

    更改请求 URL 以匹配您服务器的 GraphQL 端点 确保请求的方法是 POST,而不是 GET 在Body 下,选择x-www-form-urlencodedquery 添加为key,并将整个查询字符串添加为value 如果您有任何变量,请添加一个 variables 键并将它们作为 value 包含在内(它们需要是格式正确的 JSON)。

使用 GET:

    更改请求 URL 以匹配您服务器的 GraphQL 端点 确保请求的方法是 GET 将query 添加为key,并将整个查询字符串添加为valueParams 如果您有任何变量,请添加 variables 参数并将它们作为 value 包含在内(它们需要是格式正确的 JSON)。

或者...

如果您正在构建一个 GraphQL 服务器,您可能会发现公开一个 Graph i QL 端点来测试您的查询要容易得多。你可以阅读更多关于它的信息here。

它已融入graphql-server-express(请参阅文档here)和express-graphql(文档here)。

编辑:就从您的请求中处理数据而言:是的,您可以在解析器函数中读取您的请求并指定要返回的数据。但是,每个resolve() 函数都与特定字段绑定,该字段返回特定类型。查询和突变本身只不过是“根查询”或“根突变”类型上的字段,这就是它们也具有解析功能的原因。

您的secretMessage 查询解析为secretMessage 类型,但您将其解析为字符串。如果您尝试运行该查询,它将始终返回 null 作为结果。相反,如果您希望它返回一个具有您根据传入的参数修改的 name 属性的对象,您可以这样做:

resolve(parVal, args) 
  return  name: `$args.nametest` ;
,

现在,如果您执行如下查询:

query MyQuery 
  secretMessage(name: "John") 
    name
  

你应该回来了:


  "data": 
    "secretMessage": 
      "name": "Johntest"
    
  

您还可以为您的name 字段指定一个解析器,以达到相同的效果。如何以及何时使用解析器取决于您想要实现的目标。更详细的解释超出了此问题的范围,但我鼓励您深入研究官方文档并更好地了解解析器的工作原理。然后,您可以在此处提出后续问题(如果尚未提出问题!)。

【讨论】:

是的,目前我正在使用 express-graphql,并且我有一个服务器运行节点。我也会在编辑中将其放入问题中。 查看我的编辑以获取更多建议。确保正确格式化 axios 请求。它应该类似于: axios( method: 'POST' url: 'yoururlhere', headers: 'Content-Type': 'application/json', data: JSON.stringify(query), ) where query 是您的完整查询字符串。 谢谢丹尼尔,你的帮助肯定让我更进一步。我仍然收到关于 axios 帖子的错误请求。我已经编辑了我的原始帖子以包含它。再次感谢您对此提供的帮助。 您需要包含Content-Type 标头,就像我在上面展示的那样,否则您的正文解析器中间件将不知道它需要进行任何解析。此外,您的查询字符串格式不正确 - 您需要将其包裹在花括号中

以上是关于我是不是错误地使用了 GraphQL?我不知道它是如何向我发回数据的的主要内容,如果未能解决你的问题,请参考以下文章

GraphQL 订阅 - subscriptionsClient.subscribe 不是函数

AWSAppSync GraphQL Mutation 执行了两次

当我映射和展平数组时,TypeScript 错误地出错?

如果使用了错误的方法并且我不知道资源是不是存在,我应该回复 404 还是 405?

使用 cognito 进行 Appsync graphql 授权

GraphQL 期望 Iterable,但没有为字段 xxx.yyy 找到一个