如何使用提取将GraphQL API的表单数据以JSON格式发布为JSON? [英] How to use fetch to POST form data as JSON for GraphQL API?

查看:120
本文介绍了如何使用提取将GraphQL API的表单数据以JSON格式发布为JSON?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我希望在单击注册"后从注册表单输入数据时,按钮,数据将发送到GraphQL,然后输入到mongoDB中.运动场中的GraphQL查询有效,但是我希望在注册和授权表单中输入数据后,数据库中的数据才能显示.

I want that when entering data from the registration form after clicking on the "Register" button, the data is sent to GraphQL and then entered into mongoDB. GraphQL queries in the playground works, but I want the data in the database to appear after I enter the data in the registration and authorization form.

点击注册按钮后,写入"POST正文丢失".您忘了使用body-parser中间件吗?"

After clicking on the register button, writes "POST body missing. Did you forget use body-parser middleware?"

我正在使用Node.js,GraphQL和mongoDB.

I'm using Node.js, GraphQL and mongoDB.

Submit.js:

Submit.js:

const regForm = document.getElementById("reg-form");

regForm.addEventListener("submit", handleFormSubmit);

async function handleFormSubmit(event) {
    event.preventDefault();

    const form = event.currentTarget;

    const url = form.action;

    try {
        const formData = new FormData (form);

        const responseData = await postFormDataAsJson({ url, formData });

        console.log({ responseData });

    } catch (error) {
        console.error(error);
    }
}

async function postFormDataAsJson({ url, formData }) {
    const plainFormData = Object.fromEntries(formData.entries());
    const formDataJsonString = JSON.stringify(plainFormData);

    const fetchOptions = {
        method: "POST",
        headers: {
            "Content-Type": "application/json",
            "Accept": "application/json"
        },

        body: formDataJsonString,
    };

    const response = await fetch(url, fetchOptions);

    if (!response.ok) {
        const errorMessage = await response.text();
        throw new Error(errorMessage);
    }
    return response.json();
}

const bodyParser = require("body-parser");

app.use(bodyParser.json());

app.post("http://localhost:4000/graphql", (request, response) => {

    const newUser = {
        firstName: request.body.firstName,
        telephone: request.body.telephone,
        email: request.body.email,
        password: request.body.password
    };
    response.status(201).json(newUser);
});

index.js(服务器):

index.js (server):

const { ApolloServer, gql, PubSub} = require('apollo-server');
const resolvers = require('./resolvers');
const typeDefs = require('./typeDefs.js');
const mongoose = require('mongoose');
mongoose.set("useUnifiedTopology", true);

const pubSub = new PubSub();

const server = new ApolloServer({
    typeDefs,
    resolvers,
    context: ({ req }) => ({ req, pubSub })
});

mongoose
.connect('..., 
{useNewUrlParser: true})
.then(() => {
    console.log('mongoDB is connected');
    return server.listen();
})
.then(res => {
    console.log(`Server is running at ${res.url}`);
})
.catch(err => {
    console.log(err);
});

typeDefs.js:

typeDefs.js:

const { gql } = require('apollo-server');

module.exports = gql`
    type Article {
        id: ID!
        title: String
        subtitle: String
        description: String
        date: String
        firstName: User!
    }
    type User {
        id: ID!
        firstName: String!
        token: String!
        email: String!
        telephone: String!
    }
    type Query {
        getArticles: [Article]
        getArticle(id: ID!): Article
    }
    input InputRegister {
        firstName: String!
        telephone: String!
        email: String!
        password: String!  
    }
    type Mutation {
        register(inputData: InputRegister): User!   
        login(email: String!, password: String!): User
        addArticle(title: String!, subtitle: String!, description: String!, firstName: String!, date: String) : Article!
        deleteArticle(id: ID!): Article!
    }
    type Subscription {
        newArticle: Article!
    }
`;

user.js(模型):

user.js (Model):

const { model, Schema} = require('mongoose');

const newUser = new Schema({
    firstName: String,
    telephone: String,
    email: String,
    password: String
})

module.exports = model('User', newUser)

推荐答案

好吧,错误提示您没有任何东西可以解析正文,而且我看不到代码中使用了任何框架.通常,您将有一个框架通过一些解析库来实现.不过,如果您希望没有它就做.在这里很好地解释了,请查找:如何在没有框架的情况下进行解析

Well, the error states you've got nothing to parse bodies, and I didn't see any framework being used in your code. Normally, you'd have a framework do it via some parsing library. Still, if you want it done without it. Nicely explained here, look up: how to parse without a framework

我的建议是:安装Express并使用body-parser

My advice though: install express and use body-parser

本文中的代码未使用graphql,因此为什么他们使用 app.post(...)设置'/user'端点.Graphql可以在单个路由上工作.通常.../graphql.现在,您已经安装了express和apollo,只需对其进行配置.

The code in the article doesn't use graphql, hence why they're setting up the '/user' endpoint with app.post(...). Graphql is meant to work on a single route. Usually .../graphql. Now that you have installed express and apollo just configure them.

我修改了一些代码:

注意:

  • 您将必须卸载apollo-server并安装apollo-server-express
  • 甚至可以在不显式应用bodyParser来表示已弃用的情况下工作,但暂时不会损害
const express = require('express');
const bodyParser = require('body-parser');
const { ApolloServer, gql, PubSub } = require('apollo-server-express');
const mongoose = require('mongoose');

const resolvers = require('./resolvers');
const typeDefs = require('./typeDefs.js');

const pubSub = new PubSub();

const app = express();
app.use(
    bodyParser.urlencoded({
      extended: true,
    })
  );
app.use(bodyParser.json());
  
const server = new ApolloServer({
    typeDefs,
    resolvers,
    context: ({ req }) => ({ req, pubSub })
});

server.applyMiddleware({ app });
mongoose.set("useUnifiedTopology", true);

mongoose
.connect('..., 
{useNewUrlParser: true})
.then(() => {
    console.log('mongoDB is connected');
    return server.listen();
})
.then(res => {
    console.log(`Server is running at ${res.url}`);
})
.catch(err => {
    console.log(err);
});

这篇关于如何使用提取将GraphQL API的表单数据以JSON格式发布为JSON?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆