Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added example of MapCommand for extreme endpoints handling #43

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

oskardudycz
Copy link
Owner

@oskardudycz oskardudycz commented May 17, 2021

After the comment from @adrianiftode in #41.

I added an example of how to not need to define custom endpoints but have shortened extension method that will:

  • deserialise command,
  • get handler through DI,
  • handle command,
  • get the result (it there is),
  • return it.

The main endpoint mapping function looks as follows:

internal static class EndpointsExtensions
{
    internal static IEndpointRouteBuilder MapCommand<TRequest>(
        this IEndpointRouteBuilder endpoints,
        HttpMethod httpMethod,
        string url,
        HttpStatusCode statusCode = HttpStatusCode.OK)
    {
        endpoints.MapMethods(url, new []{httpMethod.ToString()} , async context =>
        {
            var command = await context.FromBody<TRequest>();

            var commandResult = await context.SendCommand(command);

            if (commandResult == CommandResult.None)
            {
                context.Response.StatusCode = (int)statusCode;
                return;
            }

            await context.ReturnJSON(commandResult.Result, statusCode);
        });

        return endpoints;
    }
}

I had to add command result to the command handler.

public interface ICommandHandler<in T>
{
    ValueTask<CommandResult> Handle(T command, CancellationToken token);
}

public record CommandResult
{
    public object? Result { get; }

    private CommandResult(object? result = null)
        => Result = result;

    public static CommandResult None => new();

    public static CommandResult Of(object result) => new(result);
}

then you could register is as:

endpoints.MapCommand<RegisterProduct>(HttpMethod.Post, "/api/products", HttpStatusCode.Created)

Still, I'm not yet convinced that's the better option. By that, you're losing:

  • Strongly typed Command (as you need to consider that you may get nulls),
  • you're losing the ability to customise the request,
  • generalising it might be hard in the long term.

I think that this could work if you're just doing the basic mapping for this particular case, and if you're not, you can fall back to the custom one.

I need to sleep through that :D I might add it into GoldenEye.

@oskardudycz oskardudycz force-pushed the extreme_cqrs_with_net5 branch 3 times, most recently from 69fef36 to fcb1f4c Compare May 17, 2021 08:57
@oskardudycz oskardudycz force-pushed the cqrs_with_net5 branch 2 times, most recently from baf083c to 5b83868 Compare May 17, 2021 10:24
@oskardudycz oskardudycz force-pushed the cqrs_with_net5 branch 2 times, most recently from 9cb8be6 to 54fdc6b Compare May 17, 2021 15:11
@oskardudycz oskardudycz force-pushed the extreme_cqrs_with_net5 branch 6 times, most recently from bb5ca4d to a1cea48 Compare May 17, 2021 19:24
@oskardudycz oskardudycz changed the base branch from cqrs_with_net5 to main May 17, 2021 19:24
@oskardudycz oskardudycz changed the base branch from main to cqrs_with_net5 May 17, 2021 19:24
@oskardudycz oskardudycz marked this pull request as draft May 17, 2021 19:26
@oskardudycz oskardudycz marked this pull request as ready for review May 17, 2021 19:26
@oskardudycz oskardudycz force-pushed the extreme_cqrs_with_net5 branch 2 times, most recently from 008724c to 4a53753 Compare May 18, 2021 06:37
Base automatically changed from cqrs_with_net5 to main May 24, 2021 06:55
@oskardudycz oskardudycz force-pushed the extreme_cqrs_with_net5 branch 2 times, most recently from 39b2d79 to 12b547f Compare May 24, 2021 07:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

1 participant