WSO2 Microgateway with Custom Filter Extensions

Hello Geeks!!! 😁😁😁

In this article, I will explain what is Custom Filter Extension and how to use with WSO2 Microgateway.

As you know, WSO2 Microgateway is an API Gateway for micro services, which is cloud-native, decentralized and developer centric.

Custom Filter Extension can use to intercept the request before send to the backend, intercept the response before send to the client same as the custom interceptors. The difference of the interceptors and filter extensions is, custom interceptor can use for the API level and resource level by defining 2 separate request and response interceptors, But the custom filter extensions is applying for request and response of all the APIs at once.

Let’s analyze a sample use case.

Eg: You have deployed multiple APIs that exposed via microgateway and you need to parse a custom header to the backend and send another custom header to the client and you need to apply that configuration to all the APIs.

So, how to achieve this??? 🧐🧐🧐

Option 1: Using Custom Request Interceptor

You can add the custom header by using a custom request interceptor and custom response interceptor. But you have to link those 2 interceptors with all the APIs. If you have 100 APIs in a single microgateway project that published on microgateway, you have to add the same interceptor to all the APIs one by one by adding the below configuration to the API definition file. (Please refer to the documentation [1] for more information about custom interceptors)

Request Interceptor: x-wso2-request-interceptorResponse Interceptor: x-wso2-response-interceptor

Option 2: Using Custom Filter Extension

You can generate the custom header in request and response flows at once by using a custom filter extension and apply to all the APIs in the Microgateway project at once. (Acting this as a Global Synapse Mediation Sequence in API Manager)

Seems to be, Option 2 is the easiest one. 😁😁😁

OK. Let’s do it. 😇😇😇

For the demonstrate purpose, I will use the WSO2 Microgateway 3.2.0 Runtime and WSO2 Microgateway 3.2.0 Toolkit versions. You can download the WSO2 Microgateway from the official website[2]

  • First we have to create a project by using the Microgateway Toolkit by executing the below command.
micro-gw init <project_name>Eg: micro-gw init SAMPLE_PROJECT
Project Initialization — WSO2 Microgateway Toolkit 3.2.0
  • Go to the <MGW_TOOLKIT_HOME>/bin/<MGW_PROJECT_HOME>/extensions directory.
Eg: <MGW_TOOLKIT_HOME>/bin/SAMPLE_PROJECT/extensions
  • Create a ballerina file that need to add the filter logic. (I have created a ballerina file named testFilterExtension.bal)
  • Inside the file, we can declare the filterRequest() method and filterResponse() method inside a class as below code sample.
import ballerina/http;public type TestFilter object {public function filterRequest(http:Caller caller, http:Request request, http:FilterContext context) returns boolean {return true;}public function filterResponse(http:Response response, http:FilterContext context) returns boolean {return true;}};

filterRequest() — We can customize the client request before send to the backend.

filterResponse() — We can customize the response that coming from the backend before send to the client side.

  • Now we have to add a custom header into the client request before send the request to the backend. For that, we can customize the filterRequest() method by calling the setHeader() method in http:Request object instance as below. (I have added a header named customRequestHeader1 with value1)
public function filterRequest(http:Caller caller, http:Request request, http:FilterContext context) returns boolean {request.setHeader("customRequestHeader1", "Value1");return true;}
  • Now we have to add a custom header into the backend response before send the response to the client side. For that, we can customize the filterResponse() method by calling the setHeader() method in http:Response object instance as below. (I have added a header named customResponseHeader1 with value2)
public function filterResponse(http:Response response, http:FilterContext context) returns boolean {response.setHeader(“customResponseHeader1”, “Value2”);return true;}
  • Finally, code of the defined filter extension similar to the below code sample.
import ballerina/http;public type TestFilter object {public function filterRequest(http:Caller caller, http:Request request, http:FilterContext context) returns boolean {request.setHeader(“customRequestHeader1”, “Value1”);return true;}public function filterResponse(http:Response response, http:FilterContext context) returns boolean {response.setHeader(“customResponseHeader1”, “Value2”);return true;}};

OK. Now you have defined a custom filter extension successfully. 😎😎 Let’s link this with the project.

  • Open the deployment-config.toml file inside the <MGW_TOOLKIT_HOME>/bin/<MGW_PROJECT_HOME>/conf directory.
Eg: <MGW_TOOLKIT_HOME>/bin/SAMPLE_PROJECT/conf
  • Add the below code to link the custom filter extension and save the file.
[[filters]]
name = “TestFilter”
position = 1

How to set the position value??? Will discuss it later. 😉😉😉

  • Build the project and generate the runtime artifact by executing the below command.
micro-gw build <PROJETC_NAME>Eg: micro-gw build SAMPLE_PROJECT
Project build — WSO2 Microgateway Toolkit 3.2.0
  • Run the runtime artifact by using the Microgateway Runtime by executing the below command.
gateway <PATH_TO_JAR_FILE>/<RUNTIME_ARTIFACT_NAME>.jarEg: gateway /home/sumudu/Documents/wso2_workspace/wso2_products/wso2am-micro-gw-toolkit-linux/3.2.0/wso2am-micro-gw-toolkit-linux-3.2.0/bin/SAMPLE_PROJECT/target/SAMPLE_PROJECT.jar
API Deployed in Runtime — WSO2 Microgateway Runtime 3.2.0

Now, let’s try to invoke the API. 😁😁😁

  • When getting the response from the Microgateway, you can see the custom header(customResponseHeader1) that configured in our custom filter extension is available as below image.
API Invocation
  • Now let’s check the backend request. (I have mocked a Webhook endpoint as the backend to the API.)
Client request in Webhook.site

You can see the custom header(customRequestHeader1) in backend request in above image. This means, our custom filter extension is working properly. 🤓🤓🤓

Furthermore, we can test this by enabling HTTP trace logs in Microgateway.

There are 2 ways to enable HTTP trace logs in WSO2 Microgateway. (Please refer to the documentation [3] for more information about debug logs and HTTP trace logs)

Method 1: Adding the property to the configuration file

  • Open the micro-gw.conf file inside the <MGW_RUNTIME_HOME>/conf directory.
  • Add the below property to the file and save.
[b7a.http]
[b7a.http.tracelog]
console = true
  • Run the runtime artifact by using the Microgateway Runtime by executing the below command.
gateway <PATH_TO_JAR_FILE>/<RUNTIME_ARTIFACT_NAME>.jarEg: gateway /home/sumudu/Documents/wso2_workspace/wso2_products/wso2am-micro-gw-toolkit-linux/3.2.0/wso2am-micro-gw-toolkit-linux-3.2.0/bin/SAMPLE_PROJECT/target/SAMPLE_PROJECT.jar

Method 2: Set command-line option in execution command.

  • Run the runtime artifact by using the Microgateway Runtime by executing the below command.
gateway <PATH_TO_JAR_FILE>/<RUNTIME_ARTIFACT_NAME>.jar --b7a.http.tracelog.console=trueEg: gateway /home/sumudu/Documents/wso2_workspace/wso2_products/wso2am-micro-gw-toolkit-linux/3.2.0/wso2am-micro-gw-toolkit-linux-3.2.0/bin/SAMPLE_PROJECT/target/SAMPLE_PROJECT.jar--b7a.http.tracelog.console=true

When you are invoking the API after enabling HTTP trace logs, you can see below information in microgateway.log file. I will explain the log information now. 😁😁😁

Part 1: Inbound Request

Inbound Request — WSO2 Microgateway Runtime 3.2.0
  • This is the request that coming from the client side and this is an Inbound Request to the microgateway. You cannot see the custom header in this place because, this header is not sending from the client side.

Part 2: Outbound Request

Outbound Request — WSO2 Microgateway Runtime 3.2.0
  • But, when you look at the above image, you can see the custom header that we defined inside the filterRequest() method in the filter extension. This is the modified client request that sending from the Microgateway to the backend. This is an Outbound Request to the Microgateway.

Part 3: Inbound Response

Inbound Response — WSO2 Microgateway Runtime 3.2.0
  • This is the actual response that came from the backend to the Microgateway and you cannot see the custom header because the backend did not send the custom header. Since this response sent from the backend, this is an Inbound Response to the Microgateway.

Part 4: Outbound Response

Outbound Response — WSO2 Microgateway Runtime 3.2.0
  • This is the response that client is received and you can see the custom header that we defined inside the filterResponse() method in the filter extension. This is the modified backend response that sending from the Microgateway to the client side. Therefore, this is an Outbound Response to the Microgateway.

OK. Now we know how to implement a custom filter extension, link the filter with the project and the way to test the behavior. But we have to understand one more thing. 🧐🧐🧐

When link the filter with the project, we have to declare a position value as below configuration in deployment-conf.toml file.

[[filters]]
name = “TestFilter”
position = 1

Position is the index of the filter to be engage the custom extension with APIs deployed in Microgateway Runtime. The position is starting from index 1. WSO2 Microgateway has set of filters as below.

Source : https://mg.docs.wso2.com/en/latest/how-tos/extensions/custom-filters/#how-to-add-a-custom-filter

You can refer to the documentation [4] for more information about custom filter extensions in WSO2 Microgateway 3.2.0

Congratulations!!! Now You can implement custom filter extensions in WSO2 Microgateway. 😇😇😇

Happy Stacking!!! 😁😁😁

[1] https://mg.docs.wso2.com/en/latest/how-tos/message-transformation/message-transformation-overview/#writing-an-interceptor

[2] https://wso2.com/api-management/api-microgateway/

[3] https://mg.docs.wso2.com/en/latest/troubleshooting/adding-debug-logs/

[4] https://mg.docs.wso2.com/en/latest/how-tos/extensions/custom-filters/

Software Engineer @ WSO2 | WSO2 Certified API Manager Expert | BIT(UCSC) | DiHN | OCPJP | Student Member of CSSL