diff --git a/docs/guide/http/integration.md b/docs/guide/http/integration.md
index ba552b91c..5dc85462f 100644
--- a/docs/guide/http/integration.md
+++ b/docs/guide/http/integration.md
@@ -1,6 +1,6 @@
# ASP.Net Core Integration
-::: TIP
+::: tip
WolverineFx.HTTP is an alternative to Minimal API or MVC Core for crafting HTTP service endpoints, but absolutely tries to be a good citizen within the greater
ASP.Net Core ecosystem and heavily utilizes much of the ASP.Net Core technical foundation. It is also perfectly possible to use
any mix of WolverineFx.HTTP, Minimal API, and MVC Core controllers within the same code base as you see fit.
@@ -19,7 +19,7 @@ Then add the `WolverineFx.HTTP` dependency with:
dotnet add package WolverineFx.HTTP
```
-::: TIP
+::: tip
The [sample project for this page is on GitHub](https://github.com/JasperFx/wolverine/tree/main/src/Samples/TodoWebService/TodoWebService).
:::
@@ -27,7 +27,9 @@ From there, let's jump into the application bootstrapping. Stealing the [sample
shifting to [Marten](https://martendb.io) for persistence just out of personal preference), this is the application bootstrapping:
+
+
```cs
using Marten;
using Oakton;
@@ -54,7 +56,7 @@ builder.Host.UseWolverine(opts =>
// This middleware will apply to the HTTP
// endpoints as well
opts.Policies.AutoApplyTransactions();
-
+
// Setting up the outbox on all locally handled
// background tasks
opts.Policies.UseDurableLocalQueues();
@@ -78,7 +80,9 @@ app.MapWolverineEndpoints();
return await app.RunOaktonCommands(args);
```
+
snippet source | anchor
+
Do note that the only thing in that sample that pertains to `WolverineFx.Http` itself is the call to `IEndpointRouteBuilder.MapWolverineEndpoints()`.
@@ -86,7 +90,9 @@ Do note that the only thing in that sample that pertains to `WolverineFx.Http` i
Let's move on to "Hello, World" with a new Wolverine http endpoint from this class we'll add to the sample project:
+
+
```cs
public class HelloEndpoint
{
@@ -94,7 +100,9 @@ public class HelloEndpoint
public string Get() => "Hello.";
}
```
+
snippet source | anchor
+
At application startup, WolverineFx.Http will find the `HelloEndpoint.Get()` method and treat it as a Wolverine http endpoint with
@@ -104,7 +112,9 @@ As you'd expect, that route will write the return value back to the HTTP respons
by this [Alba](https://jasperfx.github.io/alba) specification:
+
+
```cs
[Fact]
public async Task hello_world()
@@ -114,17 +124,21 @@ public async Task hello_world()
x.Get.Url("/");
x.Header("content-type").SingleValueShouldEqual("text/plain");
});
-
+
result.ReadAsText().ShouldBe("Hello.");
}
```
+
snippet source | anchor
+
Moving on to the actual `Todo` problem domain, let's assume we've got a class like this:
+
+
```cs
public class Todo
{
@@ -133,8 +147,10 @@ public class Todo
public bool IsComplete { get; set; }
}
```
+
snippet source | anchor
+
```cs
public class Todo
{
@@ -143,20 +159,26 @@ public class Todo
public bool IsComplete { get; set; }
}
```
+
snippet source | anchor
+
In a sample class called [TodoEndpoints](https://github.com/JasperFx/wolverine/blob/main/src/Samples/TodoWebService/TodoWebService/Endpoints.cs)
let's add an HTTP service endpoint for listing all the known `Todo` documents:
+
+
```cs
[WolverineGet("/todoitems")]
-public static Task> Get(IQuerySession session)
+public static Task> Get(IQuerySession session)
=> session.Query().ToListAsync();
```
+
snippet source | anchor
+
As you'd guess, this method will serialize all the known `Todo` documents from the database into the HTTP response
@@ -167,15 +189,19 @@ will shine in more complicated endpoints.
Consider this endpoint just to return the data for a single `Todo` document:
+
+
```cs
// Wolverine can infer the 200/404 status codes for you here
// so there's no code noise just to satisfy OpenAPI tooling
[WolverineGet("/todoitems/{id}")]
-public static Task GetTodo(int id, IQuerySession session, CancellationToken cancellation)
+public static Task GetTodo(int id, IQuerySession session, CancellationToken cancellation)
=> session.LoadAsync(id, cancellation);
```
+
snippet source | anchor
+
At this point it's effectively de rigueur for any web service to support [OpenAPI](https://www.openapis.org/) documentation directly
@@ -188,7 +214,9 @@ Now, the bread and butter for WolverineFx.Http is using it in conjunction with W
call succeeds. And, oh, yeah, let's make sure this endpoint is actively using Wolverine's [transactional outbox](/guide/durability/) support for consistency:
+
+
```cs
[WolverinePost("/todoitems")]
public static async Task Create(CreateTodo command, IDocumentSession session, IMessageBus bus)
@@ -198,11 +226,13 @@ public static async Task Create(CreateTodo command, IDocumentSession se
// Going to raise an event within out system to be processed later
await bus.PublishAsync(new TodoCreated(todo.Id));
-
+
return Results.Created($"/todoitems/{todo.Id}", todo);
}
```
+
snippet source | anchor
+
The endpoint code above is automatically enrolled in the Marten transactional middleware by simple virtue of having a
@@ -220,15 +250,17 @@ handling and response by whether or not the document actually exists. Just to sh
and also how WolverineFx.Http supports middleware, consider this more complex endpoint:
+
+
```cs
public static class UpdateTodoEndpoint
{
public static async Task<(Todo? todo, IResult result)> LoadAsync(UpdateTodo command, IDocumentSession session)
{
var todo = await session.LoadAsync(command.Id);
- return todo != null
- ? (todo, new WolverineContinue())
+ return todo != null
+ ? (todo, new WolverineContinue())
: (todo, Results.NotFound());
}
@@ -241,7 +273,9 @@ public static class UpdateTodoEndpoint
}
}
```
+
snippet source | anchor
+
## How it Works
@@ -267,7 +301,9 @@ The assemblies scanned are:
3. Any assembly that is explicitly added in the `UseWolverine()` configuration as a handler assembly as shown in the following sample code:
+
+
```cs
using var host = await Host.CreateDefaultBuilder()
.UseWolverine(opts =>
@@ -279,7 +315,9 @@ using var host = await Host.CreateDefaultBuilder()
opts.Discovery.IncludeAssembly(assembly);
}).StartAsync();
```
+
snippet source | anchor
+
::: info
@@ -291,12 +329,12 @@ In the aforementioned assemblies, Wolverine will look for **public, concrete, cl
suffixed by `Endpoint` or `Endpoints` **and also any public, concrete class with methods that are decorated by any `[WolverineVerb]` attribute**. Within these types, Wolverine is looking for **public** methods that
are decorated with one of Wolverine's HTTP method attributes:
-* `[WolverineGet]`
-* `[WolverinePut]`
-* `[WolverinePost]`
-* `[WolverineDelete]`
-* `[WolverineOptions]`
-* `[WolverineHead]`
+- `[WolverineGet]`
+- `[WolverinePut]`
+- `[WolverinePost]`
+- `[WolverineDelete]`
+- `[WolverineOptions]`
+- `[WolverineHead]`
The usage is suspiciously similar to the older `[HttpGet]` type attributes in MVC Core.
@@ -305,7 +343,7 @@ The usage is suspiciously similar to the older `[HttpGet]` type attributes in MV
Wolverine is trying to replicate the necessary OpenAPI to fully support Swashbuckle usage with Wolverine endpoints. This is
a work in process though. At this point it can at least expose:
-* HTTP status codes
-* HTTP methods
-* Input and output types when an http method either takes in JSON bodies or writes JSON responses
-* Authorization rules -- or really any ASP.Net Core attribute like `[Authorize]`
+- HTTP status codes
+- HTTP methods
+- Input and output types when an http method either takes in JSON bodies or writes JSON responses
+- Authorization rules -- or really any ASP.Net Core attribute like `[Authorize]`