Skip to content

Latest commit

 

History

History
462 lines (409 loc) · 9.58 KB

plugins.md

File metadata and controls

462 lines (409 loc) · 9.58 KB

Plugins in routing rule

Introduction

Plugin configuration has two attributes name and conf:

{
  "name": "plugin-a",
  "conf": {
    "param-name": "param-value"
  }
}

NOTE
conf attribute may not be required - it depends on plugin implementation.

Let's apply plugin-a to a request by defining it in requestPlugins attribute:

{
  "rules": [
    {
      "default": {
        "targetHost": "example.com",
        "targetPort": 80
      },
      "endpoints": [
        {
          "method": "POST",
          "pathPattern": "/user",
          "requestPlugins": [
            {
              "name": "plugin-a",
              "conf": {
                "param-name": "param-value"
              }
            }
          ]
        }
      ]
    }
  ]
}

NOTE
Plugins are configured in an array and are applied sequentially.

If you want to apply a plugin to a response, then configure it in responsePlugins attribute:

{
  "rules": [
    {
      "default": {
        "targetHost": "example.com",
        "targetPort": 80
      },
      "endpoints": [
        {
          "method": "POST",
          "pathPattern": "/user",
          "responsePlugins": [
            {
              "name": "plugin-x"
            }
          ]
        }
      ]
    }
  ]
}

Pre/post flow plugins

It is common case to apply a plugin for all endpoints (e.g. authentication) and then apply specific plugins per endpoint.

Plugins applied to a request are defined in following attributes:

  • request.preFlow.plugins
  • endpoints[].requestPlugins
  • request.postFlow.plugins

Similarly, for a response we have:

  • response.preFlow.plugins
  • endpoints[].responsePlugins
  • response.postFlow.plugins

If you want to apply a plugin before endpoint plugins then configure it in request.preFlow.plugins attribute:

{
  "rules": [
    {
      "default": {
        "targetHost": "example.com",
        "targetPort": 80
      },
      "request": {
        "preFlow": {
          "plugins": [
            {
              "name": "plugin-a",
              "conf": {
                "param-name": "param-value"
              }
            }
          ]
        }
      },
      "endpoints": [
        {
          "method": "POST",
          "pathPattern": "/user",
          "plugins": [
            {
              "name": "plugin-x"
            }
          ]
        }
      ]
    }
  ]
}

In the example above, plugin-a is applied for all endpoints in preFlow phase. In case of /user endpoint, first plugin-a is applied and then plugin-x.

If you want to apply a plugin after endpoint plugins then configure it in request.postFlow.plugins attribute:

{
  "rules": [
    {
      "default": {
        "targetHost": "example.com",
        "targetPort": 80
      },
      "request": {
        "postFlow": {
          "plugins": [
            {
              "name": "plugin-a",
              "conf": {
                "param-name": "param-value"
              }
            }
          ]
        }
      },
      "endpoints": [
        {
          "method": "POST",
          "pathPattern": "/user",
          "plugins": [
            {
              "name": "plugin-x"
            }
          ]
        }
      ]
    }
  ]
}

In the example above, plugin-c is applied for all endpoints in postFlow phase. In case of /user endpoint, first plugin-x is applied and then plugin-a.

Similarly, you can define preFlow and postFlow plugins for response of all endpoints. Define response attribute like below:

{
  "rules": [
    {
      "default": {
        "targetHost": "example.com",
        "targetPort": 80
      },
      "response": {
        "preFlow": {
          "plugins": [
            {
              "name": "plugin-x"
            }
          ]
        },
        "postFlow": {
          "plugins": [
            {
              "name": "plugin-y"
            }
          ]
        }
      },
      "endpoints": [
        {
          "method": "POST",
          "pathPattern": "/user"
        }
      ]
    }
  ]
}

The following flow diagram shows what is the order of plugins application:

This configuration snippet defines preFlow, endpoint and postFlow plugins:

{
  "rules": [
    {
      "default": {
        "targetHost": "example.com",
        "targetPort": 80
      },
      "request": {
        "preFlow": {
          "plugins": [
            {
              "name": "req-pre-1"
            },
            {
              "name": "req-pre-2"
            }
          ]
        },
        "postFlow": {
          "plugins": [
            {
              "name": "req-post-1"
            }
          ]
        }
      },
      "response": {
        "preFlow": {
          "plugins": [
            {
              "name": "resp-pre-1"
            }
          ]
        },
        "postFlow": {
          "plugins": [
            {
              "name": "resp-post-1"
            }
          ]
        }
      },
      "endpoints": [
        {
          "method": "POST",
          "pathPattern": "/user",
          "requestPlugins": [
            {
              "name": "req-end-1"
            }
          ],
          "responsePlugins": [
            {
              "name": "resp-end-1"
            }
          ]
        }
      ]
    }
  ]
}

Following diagram shows the order in which plugins are applied:

Disabling preFlow/postFlow plugins

It is possible to disable preFlow or postFlow plugins for specific endpoint. In order to disable all preFlow or postFlow plugins you should set disableAllPlugins to true.

See an example, only plugin-a and plugin-x plugins are applied:

...
"request": {
  "preFlow": {
    "plugins": [
      {
        "name": "plugin-a"
      }
    ]
  },
  "postFlow": {
    "plugins": [
      {
        "name": "plugin-b"
      }
    ]
  }
},
"endpoints": [
  {
    "method": "POST",
    "pathPattern": "/user",
    "request": {
      "postFlow": {
        "disableAllPlugins": true
      }
    },
    "requestPlugins": [
      {
        "name": "plugin-x"
      }
    ]
  }
]
...

In order to disable only some preFlow or postFlow plugins, we can put their names in disablePlugins attribute.

Let's disable plugin-b postFlow plugin:

...
"request": {
  "preFlow": {
    "plugins": [
      {
        "name": "plugin-a"
      }
    ]
  },
  "postFlow": {
    "plugins": [
      {
        "name": "plugin-b"
      }
    ]
  }
},
"endpoints": [
  {
    "method": "POST",
    "pathPattern": "/user",
    "request": {
      "postFlow": {
        "disablePlugins": ["plugin-b"]
      }
    },
    "requestPlugins": [
      {
        "name": "plugin-x"
      }
    ]
  }
]
...

Request-response plugins

So far we've seen plugins applied to request or response. However, a plugin can modify both request and response. A rule configuration for request-response plugin looks the same as for regular request plugin, but it is also applied to the response. The request-response plugins are applied to response in the reverse order they were applied to the request. After applying request-response plugins to the response, regular response plugins are applied.

Let's assume plugin-x and plugin-y are request-response plugins, plugin-a and plugin-b are response plugins. Given the following rule configuration:

...
"endpoints": [
  {
    "method": "POST",
    "pathPattern": "/user",
    "requestPlugins": [
      {
        "name": "plugin-x"
      },
      {
        "name": "plugin-y"
      }
    ],
    "requestPlugins": [
      {
        "name": "plugin-a"
      },
      {
        "name": "plugin-b"
      }
    ]
  }
]
...

First plugin-x and then plugin-y are applied to the request. After receiving response the plugins are applied to it in the following order: [plugin-y, plugin-x, plugin-a, plugin-b].

Exception handling

In request-response processing an exception can be thrown either on plugin processing request, calling target service or plugin processing response.

If an exception is thrown by a plugin processing request or on target service call then all remaining request plugins are skipped, the call to target service is aborted and the error response with 500 status code is passed to response plugins for processing.

If an exception is thrown by a plugin processing response then the response is exchanged with error response with 500 status code and passed to the remaining response plugins.

Conditional plugin application

You can configure response plugins (request plugins not supported yet) to be applied conditionally. To do so you construct a logical expression that checks against values in request/response context. If constructed expression evaluates to false then the plugin is skipped, otherwise it is applied. By default all plugins are applied.

Currently you can only check if given value can be found in an array of static values (example below).

{
  "name": "transform-response",
  "conf": {
    "headers": {
      "set": {
        "X-Correlation-Id": "$req.headers.X-Correlation-Id"
      }
    }
  },
  "applyIf": {
    "in": {
      "array": [200],
      "value": "$resp.status"
    }
  }
}

According to above configuration, transform-response will be applied only if response status code is equal to 200.