Skip to content

Add declarative Marten data requirements for handler middleware#2296

Merged
jeremydmiller merged 1 commit intomainfrom
data-requirements
Apr 6, 2026
Merged

Add declarative Marten data requirements for handler middleware#2296
jeremydmiller merged 1 commit intomainfrom
data-requirements

Conversation

@jeremydmiller
Copy link
Copy Markdown
Member

Summary

  • Implement IMartenDataRequirement support in Before/Validate middleware methods that throw RequiredDataMissingException on failure
  • Fix bug where MustNotExist was creating DocumentExists instead of DocumentDoesNotExist
  • Expand RequirementResultContinuationPolicy to handle all Before method names (not just Validate/ValidateAsync)
  • Add MartenDataRequirementFrame implementing IBatchableFrame for efficient batch querying when combined with entity loads
  • Add MartenDataRequirementContinuationStrategy detecting IMartenDataRequirement and IEnumerable<IMartenDataRequirement> returns
  • Support three handler patterns: single requirement, multiple requirements via IEnumerable, and requirement + [Entity] attribute

Test plan

  • Single IMartenDataRequirement (MustExist) happy + sad path
  • IEnumerable<IMartenDataRequirement> (MustExist + MustNotExist) happy + 2 sad paths
  • Single requirement + [Entity] attribute happy + sad path (validates batching)
  • All 7 tests passing
  • MartenTests regression check (375/381 pass, failures are pre-existing/flaky)
  • CoreTests middleware and validation tests pass

🤖 Generated with Claude Code

@jeremydmiller
Copy link
Copy Markdown
Member Author

I hate the usability on this one. Not thinking this goes in anytime soon.

@jeremydmiller
Copy link
Copy Markdown
Member Author

jeremydmiller commented Apr 6, 2026

Notes

As an easier to use alternative, let's keep the current syntax, but add attribute alternatives for declaring that a document must or must not exist first:

[DocumentDoesNotExist<User>(nameof(AddUser.UserId))]
public void Handle(AddUser command)
{

}

// assume a property named "Id" or "UserId" on the command
[DocumentExists<User>]
public void Handle(PromoteUser command)
{

}

@jeremydmiller jeremydmiller force-pushed the data-requirements branch 2 times, most recently from 2607c75 to 304a53b Compare April 6, 2026 16:19
…ocumentDoesNotExist] attributes

Introduces a data requirements system for Wolverine handlers and HTTP endpoints that
declaratively verify Marten document existence before execution. Includes:

- IMartenDataRequirement interface with batched query support
- DocumentExists<TDoc,TId> and DocumentDoesNotExist<TDoc,TId> runtime checks
- [DocumentExists<T>] and [DocumentDoesNotExist<T>] attributes for code generation
- MartenOps.Document<T>().MustExist()/MustNotExist() fluent API for Before methods
- Convention-based identity resolution ({TypeName}Id, Id, or explicit property name)
- Automatic batching of multiple requirements into a single Marten batch query
- Detach external Marten project references in favor of NuGet packages

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant