Seneca + Express 构建的微服务中文件上传的问题
Seneca & Express 构建微服务中文件上传的问题
问题描述
基于Seneca & Express 技术栈,个人准备弄一个文件存储相关的服务,其中包括了文件上传的功能。通常在只基于Express框架的实现中,常用到multer、multiparty等第三方库用于解析“multipart/form-data”这种类型的数据。然而我将Seneca & Express 组合至一起,在搭配上multer 或者 multiparty来解析“multipart/form-data”的数据时,当请求通过了解析“multipart/form-data”类型的中间件之后,请求无法传递至seneca的函数中进行处理。代码示例如下
file-service.js 启动文件相关微服务入口
// file-service.js 启动文件相关微服务入口
const path = require("path");
const Express = require("express");
const Seneca = require("seneca");
const BodyParser = require('body-parser');
const multiparty = require('multiparty');
const Web = require('seneca-web');
const ExpressAdapter = require('seneca-web-adapter-express');
const uploadAPI = require('./api/upload');
const seneca = Seneca();
const app = Express();
app.use(BodyParser.json());
app.use(BodyParser.urlencoded());
const routes = [
{
pin:"role:api,cmd:*",
prefix:"/file/api",
map:{uploadFile:{POST:true }}
}
]
let form = new multiparty.Form({ uploadDir: path.join(__dirname,"uploads") })
app.use("/file/api/uploadFile",(req,res,next)=>{
form.parse(req, (err, fields, files) => {
if (err) {
next(err);
}
next();
//文件正常处理,之后还能被Express的其他中间件处理。
})
})
const webConfig = {
routes: routes,
adapter: ExpressAdapter,
context: app
}
seneca
.use(Web, webConfig)
.use(uploadAPI)
.ready(() => {
var server = seneca.export('web/context')();
server.listen('9001', () => {
console.log('server started on:9001');
})
})
upload.js 向seneca中添加服务
// upload.js 向seneca中添加服务
module.exports = function uploadAPI(options) {
this.add({ 'role': 'api', 'cmd': 'uploadFile' }, (msg, done) => {
//请求无法传达到此处
console.log(msg.request$.query);
console.log(msg.request$.body);
console.log(msg.request$.file);
done(null, { 'success': true, 'msg': '调用成功', data: {} });
})
}
测试基本情况
- 文件能正常上传,经过文件上传相关的中间处理后能继续被Express请求链上的其他中间件继续处理,但是无法被seneca中的服务处理。
- 如果不使用文件上传的中间件,请求能直接通过,经过seneca中的服务处理后返回。
备注
- 以上代码从实际代码中截取,稍微修改,可能正常运行需要调试。
- 个人对于seneca以及express框架并没有太多深入理解过,表述可能不太清楚或者有误的地方希望各位指出。
1 回复
可以通过设置传入web插件的options,将webConfig类似一下设置,主要是将options的parseBody的属性设置为false。
const webConfig = {
routes: routes,
adapter: ExpressAdapter,
context: app,
options: {
parseBody: false
}
}
造成问题的主要原因在于express挂载解析中间件和seneca-web,seneca-web-adpater这几个第三方库冲突了。