繁体   English   中英

从阿波罗角度上传阿波罗服务器文件

[英]Apollo server file upload from apollo angular

我正在尝试使用 apollo-angular 将文件从 Angular 上传到 apollo 服务器,但文档令人困惑,而且我在类中找到的信息未更新到最新版本的 apollo angular 和 apollo 服务器。

在前端,我有:

突变

export const Save_UserMutation = gql`
  mutation SaveUserMutation ($data: UsersInput!, $file: Upload) {
   createUser(data: $data, file: $file) {
     user
   }
  }
`

服务

  save(_userData: User, emitMessage?: boolean) {
    let file = _userData.profilePicture
    _userData.profilePicture = (_userData.profilePicture as File).name

    const saveUser$ = this.apollo.mutate({
      mutation: Save_UserMutation,
      variables: {
        data: _dataUsuario,
        file
      },
      context: {
        useMultipart: true
      }
    }).subscribe()
  }

在后端:

服务器

const server = new ApolloServer({
  schema,
  context: createContext,
  uploads: false
})

上传设置为 false 就像文档说的https://www.apollographql.com/docs/apollo-server/data/file-uploads/#gatsby-focus-wrapper

用nexus写的突变

export const UsersMutation = extendType({
    type: 'Mutation',
    definition(t) {

        t.nonNull.field('createUser', {
            type: 'Users',
            args: {
                data: nonNull(arg({ type: 'UsersInput' })),
                file: arg({
                    type: GraphQLUpload
                })
            },
            async resolve(parent, args, ctx) {
              
                if (args.file) {
                    const { createReadStream, filename, mimetype, encoding } = await args.file
                    const stream = createReadStream()
                    const pathName = path.join(__dirname, 'public', 'profilePictures') + `/${filename}`
                    await stream.pipe(fs.createWriteStream(pathName))
                    args.data.profilePicture == pathName
                }

                args.data.password = await bcrypt.hash(args.data.password, 10)
                return ctx.prisma.users.create({
                    data: args.data
                })
            }
        }),
})

当我尝试上传文件时,出现以下错误。

POST body missing. Did you forget use body-parser middleware?

最后,我找到了如何使它工作阅读 graphql-upload 库文档的详细信息。

在设置标题中说。

在 GraphQL 中间件之前使用 graphqlUploadKoa 或 graphqlUploadExpress 中间件。 或者,使用 processRequest 创建自定义中间件。

我没有实施任何选项,因此未处理请求。

我从 Apollo Server 改为 apollo server express 并添加了 graphqlUploadExpress 作为中间件

服务器.ts

import { ApolloServer } from 'apollo-server-express'
import { createContext } from './context'
import { schema } from './schema'
import express from 'express'
import { graphqlUploadExpress } from 'graphql-upload';
import path from 'path';
import dotenv from 'dotenv'

dotenv.config()

const app = express();
const PORT = process.env.PORT || 4000

const server = new ApolloServer({
  schema,
  context: createContext,
  uploads: false
})

let publicPath = path.join(__dirname, '..', 'public')

app.use(express.static(publicPath))

app.use(
  '/graphql',
  graphqlUploadExpress({ maxFileSize: 10000000, maxFiles: 10 })
)

server.applyMiddleware({ app })

app.listen({ port: PORT }, () => {
  console.log(`Server running on port ${PORT}`)
})

当我使用 nexus 时,在我的模式定义文件中我定义了一个标量:

架构定义文件

export const Upload = scalarType({
    name: GraphQLUpload.name,
    asNexusMethod: 'upload', // We set this to be used as a method later as `t.upload()` if needed
    description: GraphQLUpload.description,
    serialize: GraphQLUpload.serialize,
    parseValue: GraphQLUpload.parseValue,
    parseLiteral: GraphQLUpload.parseLiteral,
});

然后我在突变参数中使用上传类型来访问文件信息并将其保存在文件系统上。

  t.nonNull.field('createUser', {
            type: 'userMutationResponse',
            args: {
                data: nonNull(arg({ type: 'UsersInput' })),
                file: arg({ type: 'Upload' })
            },
            async resolve(parent, args, ctx) {

                if (args.file) {
        const { createReadStream, filename, mimetype, encoding } = await file
        const stream = createReadStream()
        let newFilename = modFilename(filename)
        const pathName = path.join(__dirname, '..', '..', 'public', 'profilePictures') + `/${newFilename}`
        await stream.pipe(fs.createWriteStream(pathName))


                }

                args.data.password = await bcrypt.hash(args.data.password, 10)

                const userCreated = await ctx.prisma.users.create({ data: args.data })

                userCreated.profilePicture = new URL('profilePictures/' + userCreated.profilePicture, process.env.URI).toString()

                return userCreated                }
        }),

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM