moleculerjs / moleculer-web

:earth_africa: Official API Gateway service for Moleculer framework
http://moleculer.services/docs/moleculer-web.html
MIT License
291 stars 118 forks source link

Disabling bodyParsers for a specific endpoint of routes path #236

Closed cfrome77 closed 3 years ago

cfrome77 commented 3 years ago

when using moleculer-web as an apiGateway is it possible to disable bodyParsers for specific aliases on a route path? If not is possible that a new route be created with the same path and implement a whitlelist for the specific endpoint? There are service files with actions in the implementation that all use the /api route path.

A servie file with an actions was implemented to upload files (/api/v1/upload) and as the documentation mentions needs to have bodyParsers disabled. I would like for the other api path routes (api/v1/permissions, api/v1/user, etc...) to be able to continue using the bodyParsers functionality. Please let me know what I may be missing. Currently when I try to call the action (api/v1/upload) the params in ctx comes back as empty, yet the 200 response in swagger shows the data in the browser network. Currently the service file is just printing the ctx to make sure the file data is coming back, which it is currently not.

ctx showing empty param object image

/api routes path in api.service.js

 {
                path: "/api",

                whitelist: [
                    "**"
                ],

                // Global CORS settings for all routes
                cors: {
                    // Configures the Access-Control-Allow-Origin CORS header.
                    origin: "*",
                    // Configures the Access-Control-Allow-Methods CORS header. 
                    methods: ["GET", "OPTIONS", "POST", "PUT", "DELETE"],
                    // Configures the Access-Control-Allow-Headers CORS header.
                    allowedHeaders: [],
                    // Configures the Access-Control-Expose-Headers CORS header.
                    exposedHeaders: [],
                    // Configures the Access-Control-Allow-Credentials CORS header.
                    credentials: false,
                    // Configures the Access-Control-Max-Age CORS header.
                    maxAge: 3600
                },

                // Route-level Express middlewares. More info: https://moleculer.services/docs/0.14/moleculer-web.html#Middlewares
                use: [],

                // Enable/disable parameter merging method. More info: https://moleculer.services/docs/0.14/moleculer-web.html#Disable-merging
                mergeParams: true,

                // Enable authentication. Implement the logic into `authenticate` method. More info: https://moleculer.services/docs/0.14/moleculer-web.html#Authentication
                authentication: true,

                // Enable authorization. Implement the logic into `authorize` method. More info: https://moleculer.services/docs/0.14/moleculer-web.html#Authorization
                authorization: true,

                // The auto-alias feature allows you to declare your route alias directly in your services.
                // The gateway will dynamically build the full routes from service schema.
                autoAliases: true,

                aliases: {

                },

                /** 
                 * Before call hook. You can check the request.
                 * @param {Context} ctx 
                 * @param {Object} route 
                 * @param {IncomingRequest} req 
                 * @param {ServerResponse} res 
                 * @param {Object} data
                 * 
                onBeforeCall(ctx, route, req, res) {
                    // Set request headers to context meta
                    ctx.meta.userAgent = req.headers["user-agent"];
                }, */

                /**
                 * After call hook. You can modify the data.
                 * @param {Context} ctx 
                 * @param {Object} route 
                 * @param {IncomingRequest} req 
                 * @param {ServerResponse} res 
                 * @param {Object} data
                onAfterCall(ctx, route, req, res, data) {
                    // Async function which return with Promise
                    return doSomething(ctx, res, data);
                }, */

                // Calling options. More info: https://moleculer.services/docs/0.14/moleculer-web.html#Calling-options
                callingOptions: {},

                bodyParsers: {
                    json: {
                        strict: false,
                        limit: "1MB"
                    },
                    urlencoded: {
                        extended: true,
                        limit: "1MB"
                    }
                },

                // Mapping policy setting. More info: https://moleculer.services/docs/0.14/moleculer-web.html#Mapping-policy
                mappingPolicy: "all", // Available values: "all", "restrict"

                // Enable/disable logging
                logging: true
            }

file.service.js


module.exports = {
    name: "file",
    version: 1,

    /**
     * Settings
     */
    settings: {

    },

    /**
     * Action Hooks
     */
    hooks: {
        before: {
            /**
             * Register a before hook for the `create` action.
             * It sets a default value for the quantity field.
             *
             * @param {Context} ctx
             */
            // create(ctx) {
            // }
        }
    },

    /**
     * Actions
     */
    actions: {
        /**
         * The "moleculer-db" mixin registers the following actions:
         *  - list
         *  - find
         *  - count
         *  - create
         *  - insert
         *  - update
         *  - remove
         */
        upload: {
            rest: "POST /upload",
            async handler(ctx) {
                console.log(ctx);
            }
        }
    }
};
intech commented 3 years ago

https://codesandbox.io/s/moleculer-issue-236-pl83k You can solve your problem in this way, separating the file upload and other requests at the route level.

cfrome77 commented 3 years ago

@intech thanks for the reply and the codesandbox example. The example is extremly helpful. Separating the paths at the route level looks like exactly what I should be doing.

Canario0 commented 2 years ago

@intech the sand box is not working anymore. Do u have the code uploaded anywhere ?

intech commented 2 years ago

@Canario0 I can't write a new code example right now. Routes have a global path in settings and have a path into each group of routes with custom settings https://moleculer.services/docs/0.14/moleculer-web.html#File-upload-aliases. First, you need to designate a common Path for all routes. And then, inside the routes array, separate them and set different bodyParser and aliases settings https://moleculer.services/docs/0.14/moleculer-web.html#Multiple-routes. Using examples from the documentation and small tests, you can figure it out yourself.