Code review comment for lp:~leonardr/lazr.restful/generate-multiversion-operations

Revision history for this message
Leonard Richardson (leonardr) wrote :

This branch adds version information to all generated named operations, and introduces two new declarations (@operation_for_version and @operation_removed_in_version) that let you publish the same underlying Python method differently in different versions of the web service.

Each web service version can apply its own set of annotations to a given method, possibly even making a drastic change like changing an operation from a read operation to a write operation. By default, annotations are inherited from earlier versions, and if a particular version does not modify a named operation at all, it inherits the previous version's implementation (or lack of an implementation).

Because the list of versions is not available at the time these annotations are being processed, I use None to designate the earliest version in the web service. All subsequent versions that I need to deal with are passed as arguments to @operation_for_version and @operation_removed_in_version, so I can just use those strings. If the developer passes versions into those annotations that turn out not to be in the IWebServiceConfiguration version list, an error will happen during the second stage of ZCML processing.

I add a new type of operation to OPERATION_TYPES, 'removed_operation'. When iterating over an interface definition, this makes it easy to notice an operation that was present in older versions but not in the latest version. Simply removing the 'type' annotation makes it look like the method was incompletely defined.

The core of the code is in metazcml#register_webservice_operations, which takes code that used to be run only once, and runs it once for every versioned set of annotations. Because register_webservice_operations does not have access to the IWebServiceVersion marker interfaces, it can't register the operations directly. Instead, it passes the version name into register_adapter_for_version(), which runs later, after the IWebServiceVersion interfaces have been created. This function looks up the IWebServiceVersion utility given the version name, and registers the named operation with that versioned marker interface, so that it will only be used for that version of the web service.

generate_operation_adapter() now takes a version number, and generates the appropriate adapter class for that version, using that version's annotations.

Adapter lookups for operations no longer work if you check against IWebServiceRequestVersion. You need to check against a specific versioned request interface. This caused several miscellaneous test failures.

« Back to merge proposal