PayU / openapi-validator-middleware

Input validation using Swagger (Open API) and ajv
Apache License 2.0
144 stars 50 forks source link

Handling different baseUrl when using firebase functions #120

Open manwithsteelnerves opened 4 years ago

manwithsteelnerves commented 4 years ago

When using firebase functions, the baseUrl is pre-fixed with the region+function name and this is dynamically added at the time of launching the cloud function.

Is there any way to handle without modifying the input spec baseUrl?

const path = req.baseUrl.concat(req.route.path);

The above code is not matching the path that was added in the spec. As we maintain different environments during development, its not possible to provide multiple schema json in init just to avoid this problem

Any solutions would be great!

larssn commented 3 years ago

Think I have the same problem. validate does absolutely nothing. I'm thinking it doesn't match the path.

@manwithsteelnerves Did you find a solution?

manwithsteelnerves commented 3 years ago

@larssn Are you using cloud functions? If so, you can try this hack.

import  { init, validate as internalValidate }  from    'openapi-validator-middleware';
init(path-to-schema, options);

export const validator = {
    validate  : () => (req: any, res: any, next: Function) => {
        req.baseUrl = req.baseUrl.replace(req.baseUrlPrefix , ""); //This is the patch

        console.time("Validate Request");
        internalValidate(req, res, next);
        console.timeEnd("Validate Request");

    }
}

We call validator.validate from our routes as a middleware call.

larssn commented 3 years ago

Thanks for the quick response!

We are indeed using cloud functions. However our Request object does not have a baseUrlPrefix, and the baseUrl is an empty string. Googling baseUrlPrefix doesn't yield much, is it a custom field you've made?

larssn commented 3 years ago

Figured it out, we had to do:

   validate  : () => (req: any, res: any, next: Function) => {
        req.baseUrl = '/v1';

        console.time("Validate Request");
        internalValidate(req, res, next);
        console.timeEnd("Validate Request");
    }

Thanks for the hint. Saved us some time!

manwithsteelnerves commented 3 years ago

I forgot to add how we have the baseUrlPrefix

router.use("/", async (req : express.Request, res : express.Response, next : express.NextFunction) => {
    req.locals = { context : {}};
    req.baseUrlPrefix = req.baseUrl; //Save this
    next();
});

We saved it in at very first router to avoid hardcoding :) Sorry for not mentioning it!

kobik commented 3 years ago

@larssn @manwithsteelnerves glad to see you've managed.

Adding a baseUrlPrefix sounds like a legitimate feature and we'll consider adding that.

manwithsteelnerves commented 3 years ago

Great! Just a small change. Would be good if its req.locals.baseUrlPrefix