JS Middleware Performance

Imported Google Group message. Original thread at: Redirecting to Google Groups Import Date: 2016-01-19 21:04:24 +0000.
Sender:alex.gadea.
Date:Sunday, 1 February 2015 18:52:46 UTC.

The addition of JS middleware is a very exciting development. I have a question about a specific use case and how the middleware will perform. In our case, the body payload will need to be parsed and modified (properties renamed and in some cases deleted). Will each request have its own sandbox created or is there one sandbox that is created and shared between all requests. Our primary concern is performance and JS is not the speediest at encoding/decoding JSON. One alternative is to build middleware in Go to handle the decoding and re-encoding. Is there the capability to add our own Go middleware or would we simply fork the current code base if Go was the path we wanted to take for this particular functionality?

Thanks,
Alex

Imported Google Group message.
Sender:Martin Buhr.
Date:Sunday, 1 February 2015 20:04:24 UTC.

Hi Alex,

Each middleware has one sandbox per API, and the middleware object is loaded into memory during the initial load of the API Configuration, which means when a request comes in, it’s just another function, and doesn;t need to bootstrap.

It really depends on what kind of performance hit you want to take, the JS middleware can add up to 80ms to a request (in a 200 req p/s load test), not fantastic, but it’s something we’re looking to optimise over time.

However, if high performance is what you need, we’d recommend forking the code and using our middleware interface to manually add it to the chain, that would add minimal overhead per request. Extending Tyk is pretty straightforward, most features we introduce are actually just middleware components that use the TykMiddleware Interface. We made the middleware interface an easily repeatable pattern (there’s a sample component in the master branch called sample_middleware.go), adding it to the chain is then only a matter of inserting it into a list in the main file.

On the other hand, we realise that body transformation is something that our users will want, and we need to figure out a good way of making a pipeline possible, so if you do decide to go down the middleware approach, let me know directly, happy to help out, especially if we can generalise it.

Cheers,
Martin

  • show quoted text -

Imported Google Group message.
Sender:Martin Buhr.
Date:Monday, 2 February 2015 14:16:08 UTC.

Hi Alex,

Me again - I just wanted to let you know that we just pushed a new middleware component to our master branch, this will be going into the next release. This middleware component addresses exactly your use case, with some added flexibility.

The new module is called Transform middleware, and allows you to create a template file using Golangs template syntax and assign incomming fields to anywhere you like, this includes lists and maps, so for example:

Input (inbound request):
{
“value1”: “value-1”,
“value2”: “value-2”,
“value_list”: [
“one”,
“two”,
“three”
]
}

Template:
{
“value1”: “{{.value2}}”,
“value2”: “{{.value1}}”,
“transformed_list”: [
{{range $index, $element := .value_list}}
{{if $index}}
, “{{$element}}”
{{else}}
“{{$element}}”
{{end}}
{{end}}
]
}

Outbound body of message:
{
“value1”: “value-2”,
“value2”: “value-1”,
“transformed_list”: [
“one”,
“two”,
“three”
]
}

This is the most flexible approach I can see without resorting to JSONPath or any other odd mapping objects. This approach unfortunately does not work with XML, but we’ll get there eventually.

Configuration of templates can be done on a per-path basis, this will perform MUCH faster than using the JS middleware, as everything is handled using go primitives and the templates are pre-loaded at start and so only need to be parsed once.

Hope that helps :slight_smile:

Thanks,
Martin

On Sunday, February 1, 2015 at 6:52:46 PM UTC, alex.gadea wrote:

  • show quoted text -