Quiero cargar varias imágenes en una solicitud POST. Actualmente, la parte de mi solicitud relacionada con la carga de archivos está tomando un archivo y se ve así:
return try req.content.decode(File.self).flatMap(to: Image.self) { (file) in try file.data.write(to: URL(fileURLWithPath: DirectoryConfig.detect().workDir + localImageStorage + file.filename)) return try Image(userID: user.requireID(), url: imageStorage + file.filename, filename: file.filename).save(on: req) } Esto funciona bien. Ahora, traté de cambiar .decode(File.self) a .decode([File].self) y hacer un bucle para todos los archivos.
Cuando intento cargar imágenes usando el parámetro data[] en Postman, aparece el siguiente error:
No se admite la decodificación de datos de formulario anidados.
¿Cómo puedo solucionar esto?
El siguiente ejemplo funciona bien, probado varias veces ya 🙂
struct MyPayload: Content { var somefiles: [File] } func myUpload(_ req: Request) -> Future<HTTPStatus> { let user: User = try req.requireAuthenticated() return try req.content.decode(MyPayload.self).flatMap { payload in let workDir = DirectoryConfig.detect().workDir return payload.somefiles.map { file in let url = URL(fileURLWithPath: workDir + localImageStorage + file.filename) try file.data.write(to: url) return try Image(userID: user.requireID(), url: imageStorage + file.filename, filename: file.filename).save(on: req).transform(to: ()) }.flatten(on: req).transform(to: .ok) } }por cierto, también podría declarar su carga útil exactamente en los parámetros de la función
func myUpload(_ req: Request, _ payload: MyPayload) -> Future<HTTPStatus> { let user: User = try req.requireAuthenticated() let workDir = DirectoryConfig.detect().workDir return payload.somefiles.map { file in let url = URL(fileURLWithPath: workDir + localImageStorage + file.filename) try file.data.write(to: url) return try Image(userID: user.requireID(), url: imageStorage + file.filename, filename: file.filename).save(on: req).transform(to: ()) }.flatten(on: req).transform(to: .ok) }la única diferencia está en declarar la función de punto final en el enrutador
router.post("upload", use: myUpload)contra
router.post(MyPayload.self, at: "upload", use: myUpload)