v5: Safe way to rename / remove / relocate fields
- Dominant language
- TypeScript
- Stars
- 12.9k
- Forks
- 625
- Avg merge
- 5h 23m
- Merged PRs (30d)
- 24
Description
# v5: Safe way to rename / remove / relocate fields (e.g. move `totalCount` into `aggregate.count` for Hasura-style aggregates)
Hi 👋. I’m using PostGraphile v5 with `@graphile/pg-aggregates` and Grafast, and I’m trying to build a plugin that reshapes the *entire* schema for connection types to look more like Hasura’s aggregate API.
Concretely, for any GraphQL object type that:
- is backed by a `ConnectionStep` (i.e. `Self.extensions.grafast.assertStep.$$export.exportName === "ConnectionStep"`), and
- exposes one of the aggregate fields added by `@graphile/pg-aggregates` (e.g. `aggregates`, `aggregate`, `groupedAggregates`),
I’d like to be able to:
1. **Rename fields** (e.g. rename a connection root field or `aggregates` → `aggregate`).
2. **Remove fields** at the connection level (e.g. hide `totalCount` / `count` from the top level).
3. **Clone / relocate fields** while preserving their Grafast plan (e.g. move `totalCount` so that it is also available as `aggregate.count` inside the aggregate container).
The end goal is a Hasura-like shape such as:
```graphql
foo_aggregate {
aggregate {
count
sum { ... }
avg { ... }
}
groupedAggregate { ... }
}
```
…where `aggregate.count` behaves exactly like the existing `totalCount`/`count` on the connection (same semantics, same plan), and ideally we can optionally drop the top-level `totalCount` field.
## What I tried
I experimented with:
- `schema.hooks.GraphQLObjectType_fields` (v5 hook API), and
- `processSchema(...)` post-build transformations, and
- copying the `GraphQLField` / `GraphQLFieldConfig` and/or `extensions.grafast` from the connection’s `totalCount` field into the aggregate container type.
This “works” at the type level (the new `aggregate.count` field appears in the schema), but at runtime it tends to break the aggregate object resolution – `aggregate` becomes `null` – because the copied plan was written assuming the parent step is the connection step, not the aggregate step.
In other words, naïvely cloning the field or its plan isn’t safe without deeper knowledge of the internal Step graph.
## Request
Would it be possible to have either:
- A **documented pattern / example plugin** that shows how to:
- rename / hide fields on `ConnectionStep`-backed types, and
- expose a `count` field inside the aggregate container that reuses the existing connection-level `totalCount` logic **safely**, or
- A **first-class option in `@graphile/pg-aggregates` / core** that exposes a Hasura-style `aggregate.count` (optionally also allowing the top-level `totalCount` to be removed), or
- A small **API hook** that lets a plugin get from the aggregate Step back to the underlying connection Step (so a custom `aggregate.count` plan can delegate to the same logic as `totalCount` without relying on internal, undocumented assumptions)?
I’m specifically trying to avoid:
- casting everything to `any` and poking at private properties, and
- brittle hacks that rely on internal Step structures that may change.
A supported way to do “rename / remove / relocate field while preserving its Grafast plan” for connection/aggregate types would make Hasura-style compatibility much easier to maintain.
Thanks a lot for any guidance or API hooks you can provide 🙏
Contributor guide
Assessment
This issue has not been assessed yet.