Skip to content

Marten Operation Side Effects

TIP

You can certainly write your own IMartenOp implementations and use them as return values in your Wolverine handlers

The Wolverine.Marten library includes some helpers for Wolverine side effects using Marten with the IMartenOp interface:

cs
/// <summary>
/// Interface for any kind of Marten related side effect
/// </summary>
public interface IMartenOp : ISideEffect
{
    void Execute(IDocumentSession session);
}

snippet source | anchor

The built in side effects can all be used from the MartenOps static class like this HTTP endpoint example:

cs
[WolverinePost("/invoices/{invoiceId}/pay")]
public static IMartenOp Pay([Document] Invoice invoice)
{
    invoice.Paid = true;
    return MartenOps.Store(invoice);
}

snippet source | anchor

There are existing Marten ops for storing, inserting, updating, and deleting a document. There's also a specific helper for starting a new event stream as shown below:

cs
public static class TodoListEndpoint
{
    [WolverinePost("/api/todo-lists")]
    public static (TodoCreationResponse, IStartStream) CreateTodoList(
        CreateTodoListRequest request
    )
    {
        var listId = CombGuidIdGeneration.NewGuid();
        var result = new TodoListCreated(listId, request.Title);
        var startStream = MartenOps.StartStream<TodoList>(listId, result);
       
        return (new TodoCreationResponse(listId), startStream);
    }
}

snippet source | anchor

The major advantage of using a Marten side effect is to help keep your Wolverine handlers or HTTP endpoints be a pure function that can be easily unit tested through measuring the expected return values. Using IMartenOp also helps you utilize synchronous methods for your logic, even though at runtime Wolverine itself will be wrapping asynchronous code about your simpler, synchronous code.

Released under the MIT License.