SkillAgentSearch skills...

Squiggly

The Squiggly Filter is a Jackson JSON PropertyFilter, which selects properties of an object/list/map using a subset of the Facebook Graph API filtering syntax.

Install / Use

/learn @bohnman/Squiggly
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

THIS PROJECT IS NO LONGER MAINTAINED

Apologies to everyone. I just don't have any time to maintain this. Feel free to fork or let me know if you're interested in taking this over.

Important Note

As of version 1.3.2, the preferred way to specify nested filters is to use square brackets intead of braces.

Preferred: assignee[firstName]

No longer Preferred but will still work: assignee{firstName}

The reason for this is that newer versions of Tomcat no longer allow braces to be specified on the url without being escaped. Square brackets are still permitted in the url and it is preferred to make the syntax url friendly.

Squiggly Filter For Jackson

Contents

<a name="what-is-it"></a>What is it?

The Squiggly Filter is a Jackson JSON PropertyFilter, which selects properties of an object/list/map using a subset of the Facebook Graph API filtering syntax.

Probably the most common use of this library is to filter fields on the querystring like so:

?fields=id,reporter[firstName]

Integrating Squiggly into your webapp is covered in Custom Integration.

<a name="prerequisites"></a>Requirements

<a name="installation"></a>Installation

Maven

<dependency>
    <groupId>com.github.bohnman</groupId>
    <artifactId>squiggly-filter-jackson</artifactId>
    <version>1.3.18</version>
</dependency>

<a name="general-usage"></a>General Usage

ObjectMapper objectMapper = Squiggly.init(new ObjectMapper(), "assignee{firstName}");
Issue object = new Issue();         // replace this with your object/collection/map here
System.out.println(SquigglyUtils.stringify(objectMapper, object));

Alternatively, if you need more control over configuring the ObjectMapper, you can do it this way:

String filterId = SquigglyPropertyFilter.FILTER_ID;
SquigglyPropertyFilter propertyFilter = new SquigglyPropertyFilter("assignee[firstName]");  // replace with your filter here
SimpleFilterProvider filterProvider = new SimpleFilterProvider().addFilter(filterId, propertyFilter);

ObjectMapper objectMapper = new ObjectMapper();
objectMapper.setFilterProvider(filterProvider);
objectMapper.addMixIn(Object.class, SquigglyPropertyFilterMixin.class);

Issue object = new Issue();         // replace this with your object/collection/map here
System.out.println(SquigglyUtils.stringify(objectMapper, object));

Also, you can generate a Plain Old Java Object (POJO) instead of a JSON String

ObjectMapper objectMapper = Squiggly.init(new ObjectMapper(), "assignee{firstName}");
System.out.println(SquigglyUtils.objectify(objectMapper, object, Object.class));

For applying filter on Collection of Objects and for returning Collection of POJOs instead of JSON String

List<User> users = Arrays.asList(
        new User("Peter", 12, "Dinklage"), 
        new User("Lena", 13, "Heady"));
String filter = "firstName,age";
ObjectMapper objectMapper = Squiggly.init(new ObjectMapper(), filter);  
List<User> filteredUsers = SquigglyUtils.listify(objectMapper, users, User.class);
// setify is also availble

<a name="reference-object"></a>Reference Object

For the filtering examples, let's use an the example object of type Issue

{
  "id": "ISSUE-1",
  "issueSummary": "Dragons Need Fed",
  "issueDetails": "I need my dragons fed pronto.",
  "reporter": {
    "firstName": "Daenerys",
    "lastName": "Targaryen"
  },
  "assignee": {
    "firstName": "Jorah",
    "lastName": "Mormont"
  },
  "actions": [
    {
      "id": null,
      "type": "COMMENT",
      "text": "I'm going to let Daario get this one.",
      "user": {
        "firstName": "Jorah",
        "lastName": "Mormont"
      }
    },
    {
      "id": null,
      "type": "CLOSE",
      "text": "All set.",
      "user": {
        "firstName": "Daario",
        "lastName": "Naharis"
      }
    }
  ],
  "properties": {
    "priority": "1",
    "email": "motherofdragons@got.com"
  }
}

<a name="top-level-filters"></a>Top-Level Filters

Select No Fields

String filter = "";
ObjectMapper mapper = Squiggly.init(mapper, filter);
System.out.println(SquigglyUtils.stringify(mapper, issue));
// prints {}

Select Single Field

filter = "id";
ObjectMapper mapper = Squiggly.init(mapper, filter);
System.out.println(SquigglyUtils.stringify(mapper, issue));
// prints {"id":"ISSUE-1"}

Select Multiple Fields

filter = "id,issueSummary"
ObjectMapper mapper = Squiggly.init(mapper, filter);
System.out.println(SquigglyUtils.stringify(mapper, issue));
// prints {"id":"ISSUE-1", "issueSummary":"Dragons Need Fed"}

Select Fields Using Wildcards

filter = "issue*";
ObjectMapper mapper = Squiggly.init(mapper, filter);
System.out.println(SquigglyUtils.stringify(mapper, issue));
// prints {"issueSummary":"Dragons Need Fed", "issueDetails": "I need my dragons fed pronto."}

Select All Fields

filter = "**";
ObjectMapper mapper = Squiggly.init(mapper, filter);
System.out.println(SquigglyUtils.stringify(mapper, issue));
// prints the same json as our example object

Select All Fields of object, but only base fields of associated objects (more on this later)

filter = "*";
ObjectMapper mapper = Squiggly.init(mapper, filter);
System.out.println(SquigglyUtils.stringify(mapper, issue));
/* prints the following:
{
  "id": "ISSUE-1",
  "issueSummary": "Dragons Need Fed",
  "issueDetails": "I need my dragons fed pronto.",
  "reporter": {
    "firstName": "Daenerys",
    "lastName": "Targaryen"
  },
  "assignee": {
    "firstName": "Jorah",
    "lastName": "Mormont"
  },
  "actions": [
    {
      "id": null,
      "type": "COMMENT",
      "text": "I'm going to let Daario get this one.."
    },
    {
      "id": null,
      "type": "CLOSE",
      "text": "All set."
    }
  ],
  "properties": {
    "priority": "1",
    "email": "motherofdragons@got.com"
  }
}
*/

<a name="nested-filters"></a>Nested Filters

Select Single Nested Field

String filter = "assignee[firstName]";
ObjectMapper mapper = Squiggly.init(mapper, filter);
System.out.println(SquigglyUtils.stringify(mapper, issue));
// prints {"assignee":{"firstName":"Jorah"}}

Select Multiple Nested Fields

String filter = "actions[text,type]";
ObjectMapper mapper = Squiggly.init(mapper, filter);
System.out.println(SquigglyUtils.stringify(mapper, issue));
// prints {"actions":[{"type":"COMMENT","text":"I'm going to let Daario get this one.."},{"type":"CLOSE","text":"All set."}]}
// NOTE: use can also use wildcards (e.g. actions{t*})

Select Same Field From Different Nested Objects

String filter = "(assignee,reporter)[firstName]";
ObjectMapper mapper = Squiggly.init(mapper, filter);
System.out.println(SquigglyUtils.stringify(mapper, issue));
// prints {"reporter":{"firstName":"Daenerys"},"assignee":{"firstName":"Jorah"}}

Select Deeply Nested Field

String filter = "actions[user[lastName]]";
ObjectMapper mapper = Squiggly.init(mapper, filter);
System.out.println(SquigglyUtils.stringify(mapper, issue));
// prints {"actions":[{"user":{"lastName":"Mormont"}},{"user":{"lastName":"Naharis"}}]}

<a name="dot-syntax"></a>Dot Syntax

As an alternative to using the braces syntax for nested filter, you can use the dot syntax

String filter = "assignee.firstName";
ObjectMapper mapper = Squiggly.init(mapper, filter);
System.out.println(SquigglyUtils.stringify(mapper, issue));
// prints {"assignee":{"firstName":"Jorah"}}

You can exclude fields using the dot syntax. Note that the exclusion applies to the last field.

String filter = "-assignee.firstName";
ObjectMapper mapper = Squiggly.init(mapper, filter);
System.out.println(SquigglyUtils.stringify(mapper, issue));
// prints {"assignee":{"lastName":"Mormont"}}

You can also combine the dot syntax with the nested syntax.

String filter = "actions.user[firstName]";
ObjectMapper mapper = Squiggly.init(mapper, filter);
System.out.println(SquigglyUtils.stringify(mapper, issue));
// prints {"actions":[{"user":{"firstName":"Jorah"}},{"user":{"firstName":"Daario"}}]}

One limitation is that you cannot use the | syntax with the dot syntax

String filter = "(actions.user,assignee)[firstName]";
ObjectMapper mapper = Squiggly.init(mapper, filter);
System.out.println(SquigglyUtils.stringify(mapper, issue));
// throws exception

<a name="regex-filters"></a>Regex Filters

In addition to using wildcards, you can also use regular expressions.

Here's an example:

String filter = "~iss[a-z]e.*~";
ObjectMapper mapper = Squiggly.init(mapper, filter);
System.out.println(SquigglyUtils.stringify(mapper, issue));
// prints {"issueSummary":"Dragons Need Fed","issueDetails":"I need my dragons fed pronto."}

Notice the tildes mark the begin and of the regex pattern.

You can also specifiy a case insensitive match.

String filter = "~iss[a-z]esumm.*~i";
ObjectMa

Related Skills

View on GitHub
GitHub Stars311
CategoryDevelopment
Updated19d ago
Forks92

Languages

Java

Security Score

95/100

Audited on Mar 15, 2026

No findings