DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports Events Over 2 million developers have joined DZone. Join Today! Thanks for visiting DZone today,
Edit Profile Manage Email Subscriptions Moderation Admin Console How to Post to DZone Article Submission Guidelines
View Profile
Sign Out
Refcards
Trend Reports
Events
Zones
Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones AWS Cloud
by AWS Developer Relations
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones
AWS Cloud
by AWS Developer Relations
Building Scalable Real-Time Apps with AstraDB and Vaadin
Register Now

Trending

  • Revolutionizing Algorithmic Trading: The Power of Reinforcement Learning
  • SRE vs. DevOps
  • 5 Key Concepts for MQTT Broker in Sparkplug Specification
  • How To Approach Java, Databases, and SQL [Video]

Trending

  • Revolutionizing Algorithmic Trading: The Power of Reinforcement Learning
  • SRE vs. DevOps
  • 5 Key Concepts for MQTT Broker in Sparkplug Specification
  • How To Approach Java, Databases, and SQL [Video]
  1. DZone
  2. Data Engineering
  3. Databases
  4. Content Filter Pattern for REST Service — Implementation

Content Filter Pattern for REST Service — Implementation

This article covers which fields should be available in the response. Today I show you how I have implemented this using DataWeave language.

Patryk Bandurski user avatar by
Patryk Bandurski
·
Jul. 15, 20 · Tutorial
Like (1)
Save
Tweet
Share
4.43K Views

Join the DZone community and get the full member experience.

Join For Free

In the last article, you can find the idea of how to introduce field filtering for your APIs. My simplified Content Filter allows for providing negative or positive filtering. The first one tells which fields Filter removes from the target response. The latter one tells which fields should be available in the response. Today I show you how I have implemented this using DataWeave language.

Filterable DataWeave Module

Okay, our input is straightforward. The Content Filter has two input arguments, like in the diagram below

content filter

Input argument for the Content Filter.

Filter Parameter

As you remember, we should be able to do positive or negative filtering. We can filter many fields that are in a comma-separated form. In order to distinguish negative filtering, each field should have a minus prefix like -type. In the case of positive filtering, no prefix is required.

I have also introduced *all keyword as a default one to represent the idea of all fields. We can combine it with both filters. Below you can see two ways of removing single type property from the object:

Java
 




x


 
1
*all,-type
2
-type



Filtered Entity

The second argument for our Content Filter is the entity on which the filter will be applied. We should be either an object or an array.

Below you find the code implementation in DataWeave.

DataWeave module:

You can reuse your DataWeave code by either creating a custom module or a mapping file. This is applied only to Mule 4. For DataWeave 1.0 we have readUrl function to read DataWeave external file.

Filterable Module

Parsing the Filter

First, we need to parse the field list. As you can see in the code below, we split the string by comma and remove the *all string if it exists.

Java
 




xxxxxxxxxx
1
13


 
1
fun parseFieldsFilter(fieldsList) =
2
    do {
3
     var fields = fieldsList default "" splitBy ","  filter (value) -> (value != "*all")
4
     ---
5
     {
6
        fields: fields,
7
        "type": fields match {
8
            case items if sizeOf (items) == 0 -> "*"
9
            case items if items every ($ startsWith "-") -> "-"
10
            else -> "+"
11
        }
12
     }
13
    }



As a result, we receive an object with the fields array and the type of filtering. Here is an example: 

Java
 




xxxxxxxxxx
1


 
1
*all,-type,-name,-surname



After applying parseFieldsFilter function, we receive: 

Java
 




xxxxxxxxxx
1


 
1
{
2
   "fields": ["-type", "-name", "-surname"],
3
   "type": "-"
4
}



For the specified example, we know that we should apply negative filtering and remove fields type, name, and surname from the output.

Filter by Match

We need to apply the filter on the supplied object. Three cases can appear:

  1. Nothing to filter, all fields should be return
  2. Remove specified fields from the output
  3. Persist only fields specified
Java
 




xxxxxxxxxx
1


 
1
fun filterItem(payload, filter) = 
2
    filter."type" match {
3
        case "*" -> payload
4
        case "-" -> negativeFilter(payload, filter)
5
        case "+" -> positiveFilter(payload, filter)
6
        else -> payload
7
    }



Function filterItem accepts payload and filter. Using the match function, we either do the negative, positive filtering, or nothing at all — more about the match you can find here.

Filter on Either Object or Array

Last one thing to consider. Content Filter should be able to apply the filter on both Object and Array types. Below you can find a code snippet with the function filterBy.

Java
 




xxxxxxxxxx
1


 
1
fun filterItem(payload, filter) = 
2
    filter."type" match {
3
        case "*" -> payload
4
        case "-" -> negativeFilter(payload, filter)
5
        case "+" -> positiveFilter(payload, filter)
6
        else -> payload
7
    }



One more time, I have used the match function to verify the incoming type. As you can see in the case of an Object, I call the filterItem function. In the case of an Array, I iterate over each element and apply the same function. Other input types the function ignores.

Apply the Logic

I have encapsulated the filtering logic within the module. Below you can see a DataWeave snippet applying the filtering logic on the payload. The list of fields to filter is coming from the field query parameters.

Java
 




x


 
1
%dw 2.0
2
output application/json
3
import filterBy from modules::FilterFieldsModule
4
---
5
filterBy(payload, attributes.queryParams.fields)



Source Code:

Source Code is available at my GitHub account here. If you have any comments or questions regarding the code don’t hesitate to write to me.

Summary

As I have stated in my previous blog post, this filtering logic may be to complex for some scenarios. However, it can be extended or simplified easily. The design and implementation, in my opinion, is in the middle – no overcomplicated. I hope that it helps to introduce filtering in your project.

Do you have any other design or implementation? Share it with the community. 

Cheers!

Filter (software) REST Web Protocols Implementation Database

Opinions expressed by DZone contributors are their own.

Trending

  • Revolutionizing Algorithmic Trading: The Power of Reinforcement Learning
  • SRE vs. DevOps
  • 5 Key Concepts for MQTT Broker in Sparkplug Specification
  • How To Approach Java, Databases, and SQL [Video]

Comments

Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com

Let's be friends: