I just submitted a PR (https://github.com/Kong/kong/pull/3840) to add getters to the PDK’s Service Request (
After digging into this, I realized that I have a concern related to the relation between:
- the setters of the Service Request,
- and the getters of Request and Service Request
In fact, the underlying Nginx data that are used to store some of the information (notably the query parameters and the HTTP headers and body) are the same whatever we are using the
pdk.service.request. This might result in confusions if, for example, the sequence below is followed:
1/ Within a plugin, get data -for example the HTTP Headers- from the Request (using
2/ Then set the HTTP headers of the Service Request using
pdk.service.request.set_headers(headers). At this stage, reading the Headers from the Service Request will obviously return the new set of headers just provided in the
3/ …but, much more confusing, reading the Headers of the Request as in step 1/ will now return the new set of Headers, and not the original one (while the “Request” is obviouly unchanged; only the Service Request is)!
This is very confusing for Plugin developers. I have the feeling that Request data should remain immutable, and setting a data in the Service Request should not affect the data of the Request.
For sure, in proxy mode, Nginx mandates the usage of specific data or functions to define the upstream data, so Kong has no other choice than setting these data (using
ngx.req.set_uri_args for the query parameters,
ngx.req.set_headers() for the headers, etc.). But when used in the PDK’s Service Request context, calling these functions also updates the Request’s original data => should Kong PDK’s rather work on “copies” of the data?
Either, similarly to the
ngx.var.upstream_urithat are used to compute some of the upstream data, we might define
ngx.var.upstream_bodydata that would be used by the Service Request setters.
They would be initialized at request reception, by copying the Request data. And then, before proxying to upstream, Kong would copy back these data to the relevant Nginx variables.
Or we might consider that the Nginx data should be used to set the upstream data in the PDK’s Service Request, and we might rather have new
ngx.var.downstream_bodydata… that would be copies of the original Request data. These new data would be set at the request reception and used by the Request getters only (no setters: they are immutable).
In both cases, plugins would always be able to get the original Requests’ data (whatever the phase they are in), and plugins that update data for upstream services (such as the Request transformer plugin) would have the capability to get and set Service Request’s data. As we have a chain of plugins, it is important for these plugins to get data from the Service Request first (may have been generated/updated by a previous plugin in the chain), and then set the updated value.
What is you feeling about this?
I did not had a look to Service Response and Response… but maybe this is the same issue…