apigee-127 / swagger-node-runner

The heart of Swagger-Node
MIT License
102 stars 124 forks source link

parameter.definition[x-alias] #67

Closed osher closed 7 years ago

osher commented 7 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 openapi-parameter-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 light non-breaking useful feature and same work can be done in fittings/swagger_params_parser.jsaround lines31~41saving an extra 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()
    }
}
theganyo commented 7 years ago

I love the idea of breaking it out.

osher commented 7 years ago

roger. I have the code working, I'll pack it later. Anyway - I need you to accept a bug fix: #68

And if you're already there - take a look at #69 too.

both backward compatible and useful...

theganyo commented 7 years ago

Everything looks good. Thanks!

osher commented 7 years ago

As promised - https://github.com/osher/swagger-params-alias Will be published to npm shortly

theganyo commented 7 years ago

Very nice.