apigee-127 / bagpipes

Less code, more flow. Let's dance!
MIT License
47 stars 30 forks source link

feature proposal: parameter.definition[x-alias] #19

Closed osher closed 8 years ago

osher commented 8 years ago

Hi.

The snippet bellow describes a fitting that allows using in parameters a custom attribute x-alias that helps support API changes concerning parameter names.

The use cases which I get to met a lot, are described as:

Having an API that changed a parameter name I would like to name in the spec only the official new name so new users will adhere to the new way

Having an API that changed a parameter name I would like to be able to decide to support the old name to help backward compatibility

And the question to you:

Now that we can officially support loading user fittings from node_modules, I may wrap it as a package such as bagpipes-fitting-params-alias with it's own tests and all, and let users cherry-pick it into their projects by adding this fitting one step before swagger_validation Yes, we're ready, lets rock.

OR - alternatively -

No, its too early from your point of view to start diverging modularity, you'd rather it as a PR into bagpipes if at all. In this case, it may not even need to be a separate step. It's a useful feature and same work can be done in fittings/swagger_params_parser.jsaround lines31~41and save a loop iteration overswagger.params` per served request.

What are your thoughts about it?

P.S: the snippet is expressed only as a thought, I did not ran it yet, but I hope the spirit is clear. it's written in ES6, but it can very easily be put in ES5 if need be, (just replace const for var and handle the destruction and arrows the old way...

const assert = require('assert');
const debug  = require('debug')('fitting:openapi_params_alias');

module.exports = function create(fittingDef) {
    debug('created');
    return openapi_params_alias;

    function openapi_params_alias(ctx, cb) {
        debug('exec');
        const req = ctx.request;
        const { params, operation } = req.swagger;

        operation.parameterObjects.forEach( parameter  => {
            const name = parameter.name;
            if (parameter.value) {
                debug('value found on official name [%s]', name);
                return;
            }

            const alias = parameter.definition['x-alias'];
            if (!alias) {
                debug('no value and no alias for [%s]', name); //if its required - validator will reject it
                return;
            }

            const aliasParam = Object.create(parameter, { name: alias });
            const aliasValue = aliasParam.getValue(req).value;

            params[name].value = aliasValue;
            debug('value of parameter [%s] was tried and %sfound under alias [%s]', name, aliasValue ? "" : "NOT ", alias, aliasValue);
        });

        cb()
    }
}
osher commented 8 years ago

oups. I think I wrote it in the wrong repository... 😛