PostGraphile v5 Connection Filter
Configure powerful filtering capabilities for your GraphQL connections.
Official Documentation
- Connection Filter Plugin: https://github.com/graphile-contrib/postgraphile-plugin-connection-filter
- Filtering (built-in): https://postgraphile.org/postgraphile/next/filtering
When to Apply
Use this skill when:
- Setting up filtering on connections
- Configuring which columns can be filtered
- Disabling relation filters to reduce API surface
- Enabling filtering on non-indexed columns
- Understanding filter operators
Quick Start
Installation
pnpm add postgraphile-plugin-connection-filter@^3.0.0-rc.1
Basic Setup
import { PostGraphileConnectionFilterPreset } from 'postgraphile-plugin-connection-filter';
const preset: GraphileConfig.Preset = {
extends: [PostGraphileConnectionFilterPreset],
};
Filter vs Condition
PostGraphile provides two ways to filter connections:
| Feature | condition (built-in) | filter (plugin) |
|---|---|---|
| Operators | Equality only | eq, ne, lt, gt, in, contains, etc. |
| Logical | No | and, or, not |
| Arrays | No | Yes |
| Relations | No | Optional |
Configuration Options
Schema Options
const preset: GraphileConfig.Preset = {
extends: [PostGraphileConnectionFilterPreset],
schema: {
// Disable relation filters (recommended for cleaner API)
connectionFilterRelations: false,
// Disable computed column filters
connectionFilterComputedColumns: false,
// Disable setof function filters
connectionFilterSetofFunctions: false,
// Keep logical operators (and, or, not)
connectionFilterLogicalOperators: true,
// Allow array filtering
connectionFilterArrays: true,
},
};
Disabling Relation Filters
The connectionFilterRelations: false option doesn't fully work. Use disablePlugins instead:
const preset: GraphileConfig.Preset = {
extends: [PostGraphileConnectionFilterPreset],
disablePlugins: [
'PgConnectionArgFilterBackwardRelationsPlugin',
'PgConnectionArgFilterForwardRelationsPlugin',
],
schema: {
// Set for documentation purposes
connectionFilterRelations: false,
},
};
Filter Operators
Comparison Operators
query {
users(filter: {
age: { eq: 25 } # Equal
age: { ne: 25 } # Not equal
age: { lt: 30 } # Less than
age: { lte: 30 } # Less than or equal
age: { gt: 18 } # Greater than
age: { gte: 18 } # Greater than or equal
age: { in: [25, 30, 35] } # In list
age: { notIn: [0, -1] } # Not in list
}) {
nodes { id name age }
}
}
String Operators
query {
users(filter: {
name: { eq: "John" }
name: { ne: "Jane" }
name: { like: "J%" } # SQL LIKE
name: { ilike: "j%" } # Case-insensitive LIKE
name: { notLike: "Admin%" }
name: { startsWith: "J" }
name: { endsWith: "son" }
name: { contains: "oh" }
name: { notContains: "admin" }
name: { in: ["John", "Jane"] }
}) {
nodes { id name }
}
}
Null Checks
query {
users(filter: {
deletedAt: { isNull: true } # IS NULL
email: { isNull: false } # IS NOT NULL
}) {
nodes { id name }
}
}
Logical Operators
query {
users(filter: {
or: [
{ role: { eq: "ADMIN" } },
{ role: { eq: "MODERATOR" } }
]
}) {
nodes { id name role }
}
}
query {
users(filter: {
and: [
{ age: { gte: 18 } },
{ age: { lt: 65 } }
]
}) {
nodes { id name age }
}
}
query {
users(filter: {
not: { status: { eq: "BANNED" } }
}) {
nodes { id name status }
}
}
Array Operators
query {
posts(filter: {
tags: { contains: ["important"] } # Array contains value
tags: { containedBy: ["a", "b", "c"] } # Array is subset
tags: { overlaps: ["urgent", "hot"] } # Arrays have common elements
tags: { anyEqualTo: "featured" } # Any element equals
}) {
nodes { id title tags }
}
}
Enabling Filtering on All Columns
By default, PostGraphile only allows filtering on indexed columns. To enable filtering on all columns:
export const EnableAllFilterColumnsPlugin: GraphileConfig.Plugin = {
name: 'EnableAllFilterColumnsPlugin',
version: '1.0.0',
schema: {
entityBehavior: {
pgCodecAttribute: {
inferred: {
after: ['postInferred'],
provides: ['enableAllFilters'],
callback(behavior) {
return [behavior, 'filterBy'];
},
},
},
},
},
};
Performance Warning: Filtering on non-indexed columns can cause slow queries. Monitor performance and add indexes as needed.
Disabling Filtering on Specific Columns
Use smart tags to disable filtering on sensitive columns:
COMMENT ON COLUMN users.password_hash IS E'@behavior -filterBy';
COMMENT ON COLUMN users.internal_id IS E'@behavior -filterBy';
Or use a plugin:
export const DisableSensitiveFiltersPlugin: GraphileConfig.Plugin = {
name: 'DisableSensitiveFiltersPlugin',
version: '1.0.0',
schema: {
entityBehavior: {
pgCodecAttribute: {
override: {
provides: ['disableSensitiveFilters'],
callback(behavior, [codec, attributeName]) {
const sensitivePatterns = ['password', 'secret', 'token', 'hash'];
if (sensitivePatterns.some(p => attributeName.toLowerCase().includes(p))) {
return [behavior, '-filterBy'];
}
return behavior;
},
},
},
},
},
};
Complete Preset Example
import type { GraphileConfig } from 'graphile-config';
import { PostGraphileConnectionFilterPreset } from 'postgraphile-plugin-connection-filter';
const EnableAllFilterColumnsPlugin: GraphileConfig.Plugin = {
name: 'EnableAllFilterColumnsPlugin',
version: '1.0.0',
schema: {
entityBehavior: {
pgCodecAttribute: {
inferred: {
after: ['postInferred'],
provides: ['enableAllFilters'],
callback(behavior) {
return [behavior, 'filterBy'];
},
},
},
},
},
};
export const FilterPreset: GraphileConfig.Preset = {
extends: [PostGraphileConnectionFilterPreset],
plugins: [EnableAllFilterColumnsPlugin],
disablePlugins: [
'PgConnectionArgFilterBackwardRelationsPlugin',
'PgConnectionArgFilterForwardRelationsPlugin',
],
schema: {
connectionFilterRelations: false,
connectionFilterComputedColumns: false,
connectionFilterSetofFunctions: false,
connectionFilterLogicalOperators: true,
connectionFilterArrays: true,
},
};
Troubleshooting
| Issue | Solution |
|---|---|
| Relation filters still appear | Use disablePlugins instead of schema option |
| Column not filterable | Check if column is indexed or use EnableAllFilterColumnsPlugin |
| Filter type missing | Ensure connection filter preset is in extends |
| Performance issues | Add indexes for frequently filtered columns |
Source Code References
- Connection Filter Plugin: https://github.com/graphile-contrib/postgraphile-plugin-connection-filter
- PgIndexBehaviorsPlugin (index-based filtering): https://github.com/graphile/crystal/blob/924b2515c6bd30e5905ac1419a25244b40c8bb4d/graphile-build/graphile-build-pg/src/plugins/PgIndexBehaviorsPlugin.ts
References
- Connection Filter Plugin (v5 compatible): https://github.com/graphile-contrib/postgraphile-plugin-connection-filter
- PostGraphile v5 Filtering Docs: https://postgraphile.org/postgraphile/next/filtering
- See
graphile-v5-behaviorsskill for controlling filterBy behavior - See
graphile-v5-presetsskill for combining filter configuration
