From 0aba6c55e7366c02d440ffc39c390b5bd0571171 Mon Sep 17 00:00:00 2001 From: Felix Winterhalter Date: Sun, 14 Jan 2024 14:20:43 +0100 Subject: [PATCH] docs: Added documentation for changes --- docs/guide/http/marten.md | 45 +++++++++++++++++-- docs/guide/http/policies.md | 41 ++++++++++++++++- .../Resources/IResourceWriterPolicy.cs | 13 +++++- .../CustomResourceWriterPolicy.cs | 10 +++++ src/Http/WolverineWebApi/Marten/Documents.cs | 6 +++ src/Http/WolverineWebApi/Program.cs | 6 +++ 6 files changed, 115 insertions(+), 6 deletions(-) create mode 100644 src/Http/WolverineWebApi/CustomResourceWriterPolicy.cs diff --git a/docs/guide/http/marten.md b/docs/guide/http/marten.md index 7309d76b0..0804a6fb5 100644 --- a/docs/guide/http/marten.md +++ b/docs/guide/http/marten.md @@ -33,7 +33,7 @@ look like this: return Results.Ok(invoice); } ``` -snippet source | anchor +snippet source | anchor Pretty straightforward, but it's a little annoying to have to scatter in all the attributes for OpenAPI and there's definitely @@ -49,7 +49,7 @@ public static Invoice Get([Document] Invoice invoice) return invoice; } ``` -snippet source | anchor +snippet source | anchor Notice that the `[Document]` attribute was able to use the "id" route parameter. By default, Wolverine is looking first @@ -66,7 +66,7 @@ public static IMartenOp Approve([Document("number")] Invoice invoice) return MartenOps.Store(invoice); } ``` -snippet source | anchor +snippet source | anchor @@ -253,3 +253,42 @@ public static (OrderStatus, Events) Post(MarkItemReady command, Order order) snippet source | anchor +### Compiled Query Resource Writer Policy + +Marten integration comes with an `IResourceWriterPolicy` policy that handles compiled queries as return types. +Register it in `WolverineHttpOptions` like this: + + + +```cs +opts.UseMartenCompiledQueryResultPolicy(); +``` +snippet source | anchor + + +If you now return a compiled query from an Endpoint the result will get directly streamed to the client as JSON. Short circuiting JSON deserialization. + + +```cs +[WolverineGet("/invoices/approved")] +public static ApprovedInvoicedCompiledQuery GetApproved() +{ + return new ApprovedInvoicedCompiledQuery(); +} +``` +snippet source | anchor + + + + +```cs +public class ApprovedInvoicedCompiledQuery : ICompiledListQuery +{ + public Expression, IEnumerable>> QueryIs() + { + return q => q.Where(x => x.Approved); + } +} +``` +snippet source | anchor + diff --git a/docs/guide/http/policies.md b/docs/guide/http/policies.md index 03d8c253b..e144c7e8f 100644 --- a/docs/guide/http/policies.md +++ b/docs/guide/http/policies.md @@ -65,7 +65,7 @@ app.MapWolverineEndpoints(opts => // Wolverine.Http.FluentValidation opts.UseFluentValidationProblemDetailMiddleware(); ``` -snippet source | anchor +snippet source | anchor The `HttpChain` model is a configuration time structure that Wolverine.Http will use at runtime to create the full @@ -97,5 +97,42 @@ app.MapWolverineEndpoints(opts => // Wolverine.Http.FluentValidation opts.UseFluentValidationProblemDetailMiddleware(); ``` -snippet source | anchor +snippet source | anchor + +## Resource Writer Policies + +Wolverine has an additional type of policy that deals with how an endpoints primary result is handled. + + + +```cs +/// +/// Use to apply custom handling to the primary result of an HTTP endpoint handler +/// +public interface IResourceWriterPolicy +{ + /// + /// Called during bootstrapping to see whether this policy can handle the chain. If yes no further policies are tried. + /// + /// The chain to test against + /// True if it applies to the chain, false otherwise + bool TryApply(HttpChain chain); +} +``` +snippet source | anchor + + +Only one of these so called resource writer policies can apply to each endpoint and there are a couple of built in policies already. + +If you need special handling of a primary return type you can implement `IResourceWriterPolicy` and register it in `WolverineHttpOptions` + + + +```cs +opts.AddResourceWriterPolicy(); +``` +snippet source | anchor + + +Resource writer policies registered this way will be applied in order before all built in policies. \ No newline at end of file diff --git a/src/Http/Wolverine.Http/Resources/IResourceWriterPolicy.cs b/src/Http/Wolverine.Http/Resources/IResourceWriterPolicy.cs index 4b23343ce..217fa88e9 100644 --- a/src/Http/Wolverine.Http/Resources/IResourceWriterPolicy.cs +++ b/src/Http/Wolverine.Http/Resources/IResourceWriterPolicy.cs @@ -1,6 +1,17 @@ namespace Wolverine.Http.Resources; +#region sample_IResourceWriterPolicy +/// +/// Use to apply custom handling to the primary result of an HTTP endpoint handler +/// public interface IResourceWriterPolicy { + /// + /// Called during bootstrapping to see whether this policy can handle the chain. If yes no further policies are tried. + /// + /// The chain to test against + /// True if it applies to the chain, false otherwise bool TryApply(HttpChain chain); -} \ No newline at end of file +} + +#endregion \ No newline at end of file diff --git a/src/Http/WolverineWebApi/CustomResourceWriterPolicy.cs b/src/Http/WolverineWebApi/CustomResourceWriterPolicy.cs new file mode 100644 index 000000000..95daa391a --- /dev/null +++ b/src/Http/WolverineWebApi/CustomResourceWriterPolicy.cs @@ -0,0 +1,10 @@ +using Wolverine.Http; +using Wolverine.Http.Resources; + +public class CustomResourceWriterPolicy : IResourceWriterPolicy +{ + public bool TryApply(HttpChain chain) + { + return false; + } +} \ No newline at end of file diff --git a/src/Http/WolverineWebApi/Marten/Documents.cs b/src/Http/WolverineWebApi/Marten/Documents.cs index 738e0ba2e..40efe2a71 100644 --- a/src/Http/WolverineWebApi/Marten/Documents.cs +++ b/src/Http/WolverineWebApi/Marten/Documents.cs @@ -57,11 +57,13 @@ public static IMartenOp Approve([Document("number")] Invoice invoice) #endregion + #region sample_compiled_query_return_endpoint [WolverineGet("/invoices/approved")] public static ApprovedInvoicedCompiledQuery GetApproved() { return new ApprovedInvoicedCompiledQuery(); } + #endregion [WolverineGet("/invoices/compiled/{id}")] public static ByIdCompiled GetCompiled(Guid id) @@ -77,6 +79,8 @@ public class Invoice public bool Approved { get; set; } } +#region sample_compiled_query_return_query + public class ApprovedInvoicedCompiledQuery : ICompiledListQuery { public Expression, IEnumerable>> QueryIs() @@ -85,6 +89,8 @@ public Expression, IEnumerable>> QueryIs } } +#endregion + public class ByIdCompiled : ICompiledQuery { public readonly Guid Id; diff --git a/src/Http/WolverineWebApi/Program.cs b/src/Http/WolverineWebApi/Program.cs index be968556d..030a13f55 100644 --- a/src/Http/WolverineWebApi/Program.cs +++ b/src/Http/WolverineWebApi/Program.cs @@ -141,13 +141,19 @@ opts.AddMiddleware(typeof(BeforeAndAfterMiddleware), chain => chain.Method.HandlerType == typeof(MiddlewareEndpoints)); +#region sample_user_marten_compiled_query_policy opts.UseMartenCompiledQueryResultPolicy(); +#endregion #region sample_register_http_middleware_by_type opts.AddMiddlewareByMessageType(typeof(FakeAuthenticationMiddleware)); opts.AddMiddlewareByMessageType(typeof(CanShipOrderMiddleWare)); #endregion +#region sample_register_resource_writer_policy + opts.AddResourceWriterPolicy(); +#endregion + // Publish messages coming from opts.PublishMessage(HttpMethod.Post, "/publish/message1").WithTags("messages"); opts.PublishMessage("/publish/message2").WithTags("messages");