node.js - NodeJS 使用 GQL 创建和 POST 文件

标签 node.js file graphql apollo-server gql

我一直无法在 NodeJS 中弄清楚如何:

  1. 从原始字符串在内存中创建一个"file";并且,
  2. 如何将该数据 POST 到另一台需要多部分/表单数据负载的服务器。

似乎您无法在 NodeJS 中使用 BlobFile 类。 我读过的模式应该是使用 Buffer 类。 我仍然无法让它与缓冲区一起工作。

我的 GQL Datasoruce 类看起来像:

const { RESTDataSource } = require('apollo-datasource-rest');
const FormData = require('form-data');

export default class MyDatasource extends RESTDataSource {

  async postFileToServer({ string }) {

    const inMemoryFile = Buffer.from(string, 'utf-8');

    const myForm = new FormData();
    myForm.append('file', inMemoryFile, 'file.txt');

    const url = 'http://examnple.com';
    const opts = { headers: { 'Content-Type': 'multipart/form-data' } };

    return await this.post(url, myForm, opts);
  }
}

当我使用 Postman 使用本地计算机上的文件进行 API 调用时,我想要访问的端点工作正常。但是,我需要 GQL 服务器从原始字符串创建文件,然后调用需要 multipart/form-data 的 example.com 端点。

上面的示例代码总是给出错误 Status 400SyntaxError: Unexpected token - in JSON at position 0

最佳答案

文件上传适合我使用apollo-datasource-rest包。这是一个例子:

server.ts:

import { ApolloServer, gql } from 'apollo-server';
import MyDatasource from './datasource';

const typeDefs = gql`
  type Query {
    dummy: String
  }
  type Mutation {
    upload: String
  }
`;
const resolvers = {
  Mutation: {
    upload(_, __, { dataSources }) {
      return dataSources.uploadAPI.postFileToServer({ str: '1234' });
    },
  },
};

const server = new ApolloServer({
  typeDefs,
  resolvers,
  dataSources: () => {
    return {
      uploadAPI: new MyDatasource(),
    };
  },
});
const port = 3001;
server.listen(port).then(({ url }) => console.log(`🚀 Server ready at ${url}`));

datasource.ts:

import { RESTDataSource } from 'apollo-datasource-rest';
import FormData from 'form-data';

export default class MyDatasource extends RESTDataSource {
  public async postFileToServer({ str }) {
    const inMemoryFile = Buffer.from(str, 'utf-8');
    const myForm = new FormData();
    myForm.append('file', inMemoryFile, 'file.txt');
    const url = 'http://localhost:3000/upload';

    return this.post(url, myForm);
  }
}

uploadServer.ts:

import multer from 'multer';
import express from 'express';
import path from 'path';

const upload = multer({ dest: path.resolve(__dirname, 'uploads/') });
const app = express();
const port = 3000;

app.post('/upload', upload.single('file'), (req, res) => {
  console.log(req.file);
  console.log(req.body);
  res.sendStatus(200);
});

app.listen(port, () => {
  console.log(`upload server is listening on http://localhost:${port}`);
});

/upload API Controller 打印的日志:

{
  fieldname: 'file',
  originalname: 'file.txt',
  encoding: '7bit',
  mimetype: 'text/plain',
  destination: '/Users/ldu020/workspace/github.com/mrdulin/apollo-graphql-tutorial/src/stackoverflow/63181608/uploads',
  filename: '3cba4dded6089479ad495e2fb2daac21',
  path: '/Users/ldu020/workspace/github.com/mrdulin/apollo-graphql-tutorial/src/stackoverflow/63181608/uploads/3cba4dded6089479ad495e2fb2daac21',
  size: 4
}
[Object: null prototype] {}

源代码:https://github.com/mrdulin/apollo-graphql-tutorial/tree/master/src/stackoverflow/63181608

关于node.js - NodeJS 使用 GQL 创建和 POST 文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63181608/

相关文章:

Node.js + MongoDB : Generating shorter ID

javascript - 我可以说 Nodejs 就像 JVM 但是是针对 JavaScript 的吗?

java - 如何将POI中的单元格输出转换为java中的文本文件

graphql - Gatsby graphiQL - 无法为不可为空的字段 ImageSharpFluid.src 返回 null

typescript - 如何从 NestJS 中的 GraphQL 解析器内部设置 session key ?

node.js - MongoDb : Error: Cannot use a writeConcern without a provided callback on remove

jquery - Bootstrap : Uncaught TypeError: Cannot read property 'fn' of undefined

php - 检查文件复制是否成功

Python,在大型 .log 文件中搜索关键字代码

graphql - 从 graphql 获取解析器级别的请求字段