[英]Upload files from Angular 7 Web App to Apollo 2.0 GraphQL Server
[英]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.