Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 20 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ title: "Changelog"
kind: reference
status: active
owner: workspace-maintainers
last_reviewed: 2026-08-26
last_reviewed: 2026-08-31
review_by: 2027-02-01
supersedes: []
---
Expand All @@ -14,6 +14,25 @@ This file is the authoritative user-facing release chronology. The former
[release-notes ledger](docs/archive/2026/graphql-orm-release-notes.md) is retained
for historical context.

## 0.28.0 - 2026-08-31

Companion macros crate: `graphql-orm-macros` **0.28.0**.

- Added repeatable, server-defined `order_expression` declarations for safe
computed-field ordering. GraphQL clients select only direction; fixed SQL
expressions are validated at compile time and never accepted from requests.
- Added opt-in `order_aggregate(name = "...", aggregate = "count")` on
relations. It generates a direction-only order field backed by a correlated
count over the relation's declared source and target keys.
- Added opt-in `graphql_complex_object` composition so handwritten complex
fields and generated, batched `GraphQLRelations` resolvers share one
async-graphql complex-object implementation.

No database or stored-data migration is required. Adding an order expression
or relation aggregate changes the entity's GraphQL order-input SDL; adding
complex-object composition preserves the existing handwritten and relation
field SDL.

## 0.27.0 - 2026-08-26

Companion macros crate: `graphql-orm-macros` **0.27.0**.
Expand Down
4 changes: 2 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ cynic-parser = { version = "=0.11.2", features = ["pretty"] }
futures = "0.3"
getrandom = "0.3"
graphql-composition = "=0.12.2"
graphql-orm = { path = "crates/graphql-orm", version = "0.27.0", default-features = false }
graphql-orm = { path = "crates/graphql-orm", version = "0.28.0", default-features = false }
graphql-orm-ai-tool-profiles = { path = "crates/graphql-orm-ai-tool-profiles", version = "0.10.2" }
graphql-orm-backup = { path = "crates/graphql-orm-backup", version = "0.7.1", default-features = false }
graphql-orm-operation-catalog = { path = "crates/graphql-orm-operation-catalog", version = "0.3.0" }
Expand Down
47 changes: 46 additions & 1 deletion MIGRATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ title: "Migration Guide"
kind: reference
status: active
owner: workspace-maintainers
last_reviewed: 2026-08-26
last_reviewed: 2026-08-31
review_by: 2027-02-01
supersedes: []
---
Expand All @@ -13,6 +13,51 @@ supersedes: []
`graphql-orm` is distributed from GitHub only. Use a reviewed full 40-character commit in `rev`;
neither the runtime nor macros crate is published to crates.io.

## 0.27.0 to 0.28.0: computed/relation ordering and complex relation composition

Computed fields can join generated ordering without a handwritten query:

```rust
#[graphql_orm(order_expression(
name = "Duration",
expression = "finished_at - started_at"
))]
```

The expression is trusted, backend-specific server configuration. Requests
continue to supply only `ASC` or `DESC`. Review the resulting query plan and
add an expression/index strategy where the selected backend supports one.

A readable relation can expose a server-generated count order without a
projection:

```rust
#[relation(
target = "StaffAssignment",
from = "id",
to = "policy_id",
multiple,
order_aggregate(name = "AssignedStaffCount", aggregate = "count")
)]
```

Requests again supply only `ASC` or `DESC`. The macro obtains the target table
from its entity type and generates the correlated count from the declared key
mapping. The initial contract supports `count` on unconditional, readable
relations; conditional relations fail compilation when combined with
`order_aggregate`.

For a relation entity that already has a handwritten `#[ComplexObject]` impl,
add `#[graphql_orm(compose_complex_object)]` to the entity and replace that
impl attribute with `#[graphql_complex_object]`. Handwritten methods remain
unchanged; generated relations retain their batching and arguments. Do not
leave both complex-object attributes on the impl.

There is no table, column, constraint, or stored-data migration. Regenerate
and review GraphQL SDL and semantic/capability fingerprints when adding a new
ordering field. Review the query plan for correlated relation counts and add
indexes on the target key columns used by frequently sorted relations.

## 0.26.0 to 0.27.0: conditional polymorphic relationships

Adopt `graphql-orm` and `graphql-orm-macros` 0.27.0 together from one reviewed
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,12 @@ schema changes explicitly.

Packages are distributed from this repository, not crates.io. Pin the reviewed
release revision, not a moving branch or tag. The current coordinated
`graphql-orm` version is 0.26.0. Replace the placeholder below with the final
`graphql-orm` version is 0.28.0. Replace the placeholder below with the final
reviewed full SHA for the release:

```toml
[dependencies]
graphql-orm = { git = "https://github.com/Dastari/graphql-orm.git", rev = "<reviewed-full-40-character-commit-sha>", version = "0.26.0", default-features = false, features = ["sqlite"] }
graphql-orm = { git = "https://github.com/Dastari/graphql-orm.git", rev = "<reviewed-full-40-character-commit-sha>", version = "0.28.0", default-features = false, features = ["sqlite"] }
```

Choose exactly the backend support needed by each service. Cargo can unify
Expand Down
2 changes: 1 addition & 1 deletion crates/graphql-orm-macros/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "graphql-orm-macros"
version = "0.27.0"
version = "0.28.0"
edition = "2024"
authors = ["Toby Martin"]
description = "Procedural macros for async-graphql and ORM-backed entities, relations, and CRUD operations."
Expand Down
19 changes: 16 additions & 3 deletions crates/graphql-orm-macros/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ title: "graphql-orm-macros"
kind: reference
status: active
owner: graphql-orm-macros-maintainers
last_reviewed: 2026-08-26
last_reviewed: 2026-08-31
review_by: 2027-02-01
supersedes: []
---
Expand All @@ -16,13 +16,13 @@ macro/runtime versions aligned:

```toml
[dependencies]
graphql-orm = { git = "https://github.com/Dastari/graphql-orm.git", rev = "<reviewed-full-40-character-commit-sha>", version = "0.27.0", default-features = false, features = ["sqlite"] }
graphql-orm = { git = "https://github.com/Dastari/graphql-orm.git", rev = "<reviewed-full-40-character-commit-sha>", version = "0.28.0", default-features = false, features = ["sqlite"] }
```

Direct use is supported for tooling that needs the macro package:

```toml
graphql-orm-macros = { git = "https://github.com/Dastari/graphql-orm.git", rev = "<reviewed-full-40-character-commit-sha>", version = "0.27.0", default-features = false, features = ["sqlite"] }
graphql-orm-macros = { git = "https://github.com/Dastari/graphql-orm.git", rev = "<reviewed-full-40-character-commit-sha>", version = "0.28.0", default-features = false, features = ["sqlite"] }
```

The direct dependency still requires a compatible `graphql-orm` runtime in the
Expand All @@ -37,6 +37,7 @@ not connect to a database, run migrations, host GraphQL, or authorize requests.
| `GraphQLSchemaEntity` | schema metadata only |
| `RepositoryEntity` | typed repository CRUD and private projections with no GraphQL surface |
| `GraphQLRelations` | batched single/composite-key relation resolvers |
| `graphql_complex_object` | handwritten complex fields composed with generated relations |
| `GraphQLOperations` | generated GraphQL root operation types and operation metadata |
| `schema_roots!` | query/mutation/subscription roots, schema builders, metadata, and resolved catalog |
| `graphql_orm_custom_operations` | semantic metadata emitted beside a handwritten root impl |
Expand Down Expand Up @@ -118,5 +119,17 @@ columns are quoted by the selected backend and all values are bound. These
logical discriminator joins require `emit_fk = false` and are enforced by
single, pageable, DataLoader, and nested bulk-preload paths.

Server-defined computed ordering uses repeatable entity-level
`graphql_orm(order_expression(name = "...", expression = "..."))`
declarations. The generated input exposes only `OrderDirection`; the fixed,
validated expression remains compile-time server configuration. Entities that
need relationship counts can add
`order_aggregate(name = "...", aggregate = "count")` to an unconditional,
readable relation; the generated correlated count uses only its declared key
mapping and target entity table. Entities that also have handwritten complex fields use
`graphql_orm(compose_complex_object)` and apply `graphql_complex_object` to the
handwritten impl so generated relations are flattened into the same
`ComplexObject` surface.

See [core runtime documentation](../graphql-orm/README.md),
and the [macro and attribute reference](../../docs/reference/graphql-orm/macros-and-attributes.md).
Loading