Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dynamically modify responses by having a callback #173

Open
cfirminofaria opened this issue Sep 23, 2020 · 2 comments
Open

Dynamically modify responses by having a callback #173

cfirminofaria opened this issue Sep 23, 2020 · 2 comments
Labels
new feature New feature

Comments

@cfirminofaria
Copy link

Would it be possible to dynamically modify responses, by having a callback? The callback, if provided, would receive the current HTTP request, the current Mock and MockResponse, the interpolated chunk and return an eventually modified chunk, headers and status. One single callback would be enough, set as an additional property on the MiddlewareConfiguration class.

This apparently simple change would allow all kinds of dynamic behaviors, like injecting values from the request into the response, call public or private APIs that provide random data, etc. etc.

Having the same functionality available through the docker container would be trickier, the callback would have to be a physical JavaScript file provided through a volume mount. My node.js knowledge doesn't go that far... Maybe the default image could have a dummy callback file that would not make any change to the response items. Maybe it's not even worth to consider, for this kind of scenarios it would be better to just let people create their own docker images.

The proposed code change would have to be applied on MockRequestHandler class (mock.request.handler.ts)

handle(request: http.IncomingMessage, response: http.ServerResponse, next: Function, params: { id: string, mock: Mock }): void {
        const _response: MockResponse = this.state.getResponse(params.mock.name, params.id);
        if (_response !== undefined) {
            const { headers } = _response;
            const { status } = _response;
            const { then } = _response;
            const delay: number = this.state.getDelay(params.mock.name, params.id);
            const jsonCallbackName = this.getJsonCallbackName(request);

            try {
                const chunk = this.getChunk(_response, params, jsonCallbackName);

// call external callback, providing request, _response, params, chunk, overwritting chunk, headers and status with returned values
// ideally, the jsonCallbackName should be applied after the external callback is invoked
// delay could also be allowed to be dynamically changed, why not?

                setTimeout(() => {
                    this.respond(params, then, response, status, headers, chunk);
                }, delay);
            } catch (e) {
                response.writeHead(HttpStatusCode.INTERNAL_SERVER_ERROR, HttpHeaders.CONTENT_TYPE_APPLICATION_JSON);
                response.end(JSON.stringify(e, ['message']));
            }
        } else {
            next();
        }
    }

Let me know if this can be easily applied into the code. This is an amazingly simple tool, covers all my mocking needs except this particular one.

Thank you

@mdasberg
Copy link
Contributor

Hi @cfirminofaria,

Thanks for your proposal, I'll have a look at it and see if we can add it.

@mdasberg mdasberg added the new feature New feature label Sep 24, 2020
@cfirminofaria
Copy link
Author

Thanks for the quick response, looking forward to having this suggestion applied.
Besides receiving the current HTTP request, the current Mock and MockResponse and the interpolated chunk, the callback could also receive the current variables:

const _variables: any = this.state.getVariables(params.id);

This would allow the callback to also use variables set by the dev interface or by one of the plugins.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
new feature New feature
Projects
None yet
Development

No branches or pull requests

2 participants