【问题标题】:How do I upload files to a graphql backend implemented using graphql-upload using axios?如何使用 axios 将文件上传到使用 graphql-upload 实现的 graphql 后端?
【发布时间】:2020-03-21 09:43:35
【问题描述】:

我有一个使用 expressexpress-graphqlgraphqlgraphql-upload 实现的 GraphQL 后端。我的 GraphQL 架构声明如下:

type OProject {
    _id: ID!
    title: String!
    theme: String!
    budget: Float!
    documentation: String!
    date: Date
}

input IProject {
    title: String!
    theme: String!
    budget: Float!
    file: Upload!
}

type Mutations {
    create(data: IProject): OProject
}

type Mutation {
    Project: Mutations
}

我想使用 axios/graphql 向我的 GraphQL API 发出 create 请求。我该怎么办?

【问题讨论】:

    标签: express graphql axios


    【解决方案1】:

    遵循 GraphQL 多部分请求规范 detailed here,您可以这样做:

    • 创建一个FormData 实例并使用以下内容填充它:
      • operations 字段,
      • map 字段和,
      • 要上传的文件

    创建 FormData 实例

    var formData = new FormData();
    

    operations 字段:

    该字段的值将是一个 JSON 字符串,其中包含 GraphQL queryvariables。您必须将variables 对象中的所有文件字段设置为空,例如:

    const query = `
        mutation($project: IProject!) {
            Project { create(data: $project) { _id } }
        }
    `;
    
    const project = {
        title: document.getElementById("project-title").value,
        theme: document.getElementById("project-theme").value,
        budget: Number(document.getElementById("project-budget").value),
        file: null
    };
    
    const operations = JSON.stringify({ query, variables: { project } });
    formData.append("operations", operations);
    

    map 字段:

    顾名思义,该字段的值将是一个对象的 JSON 字符串,其键是包含文件的 FormData 实例中的字段名称。每个字段的值将是一个数组,其中包含一个字符串,该字符串指示文件对应于值的键将绑定到 variables 对象中的哪个字段,例如:

    const map = {
        "0": ["variables.project.file"]
    };
    formData.append("map", JSON.stringify(map));
    

    要上传的文件 然后,您应该按照map 将文件添加到 FormData 实例中。在这种情况下;

    const file = document.getElementById("file").files[0];
    formData.append("0", file);
    

    就是这样。您现在可以使用 axios 和 FormData 实例向后端发出请求:

    axios({
        url: "/graphql",
        method: "post",
        data: formData
    })
        .then(response => { ... })
        .catch(error => { ... });
    

    【讨论】:

    • 嗨。我正在尝试将输入作为项目类型的对象列表发送。输入必须是列表中每个条目的文件,因此我无法链接多个文件,每个项目一个文件。知道如何实现吗?
    • 我不明白你想要达到什么目的。也许您可以提供一个代码 sn-p 显示您要发送的对象。
    猜你喜欢
    • 2021-10-19
    • 2020-09-01
    • 2019-06-30
    • 1970-01-01
    • 2020-12-04
    • 1970-01-01
    • 2019-01-15
    • 2019-12-13
    • 2017-11-18
    相关资源
    最近更新 更多