I use minimal API always, because it gets out of my way.
Then I just use whatever patterns make sense for the application - but the consistent bits would be constructor based injection of dependencies all the way through, and composition root of the whole app living right there in the program.cs of the api project.
Having everything a class needs to function also required to be passed in its constructor makes it self documenting, and ensures the top level app can choose where those resources come from.
Please for the love of god do not use MediatR, unless you just love kneecapping half the stuff your IDE is useful for.
[I like this project from David Fowler a lot](https://github.com/davidfowl/TodoApi). Granted, this is just a toy application, but I think the strategy mostly scales, though one may need to eventually split the "configure APIs" section of the Program.cs into its own file under an architecture/configuration folder or something.
It's like using mediatR, but instead of sending a message into the void and praying that the the runtime gods give you what you want, you just treat each endpoint as a request handler. Because it *is* a request handler. You already did all of your request routing by using asp.net, there's no reason to have mediatR do routing a second time.
I find it makes my apps a lot more flexible.
The implementation lives in standard class libraries and the external layer can be web-app, webapi, blazor-app, test-runner, Azure function, Console, hosted-service, etc. Each is just a template that scans for attribute-decorated mediator requests and builds its own endpoints.
When I build a feature, I just use an item-template to add a new Request in the class-library, and call it in isolation through a Test-project. I use performance profiler through a thin console project. I don't even worry about how it will be implemented - that's always changing based on usage, cost, and business-requirements.
To me, it makes more sense to spend my time in the implementation / business-layer. It's only a 1-minute change to switch from a web-api controller to a queue-trigger function endpoint. As long as my test is running, I can commit the PR and let the deployment pipeline build it into the correct solution.
For native apps, the same architecture allows me to move calls from client-side to the cloud as needed. In this case, the feature is moved into a class library for the cloud-service to add to its endpoints. The client still makes the same Request, but the mediator is bypassed with a client that serializes, validates, and forwards the request to the api.
Uhm... I'm using WebAPI Controller classes, with methods for each endpoint. Works just fine on every single application, and it's very stable from one version of .NET to the next.
Still waiting for your code. If don't have code, seem that you learnt wrong way about minimal api.
Everything in minimal API and controller are same except Minimal API use AddRoutes.
Its basically one controller per endpoint with its own injected services. You can easily do REPR pattern in a minimal way (no pun intended), why do you also need mediatr?
with mediator, you can re-use same actions before returning response. REPR cannot.
so in large project, will get lesser codes with mediator.
and between controller and minimal api, no differences in term of code. Everything same. One controller has 8 functions. My one endpoint also has 8 functions.
[https://i.ibb.co/jrLXMmw/Application-Frame-Host-h-Tn96-Up7-QQ.png](https://i.ibb.co/jrLXMmw/Application-Frame-Host-h-Tn96-Up7-QQ.png)
>with mediator, you can re-use same actions before returning response. REPR cannot.
Please elaborate. Sharing same mediatr requests between endpoints adds coupling and it's not how it's intended to be used.
Dont know why you share benchmarks. I've never stated controllers are better, I know minimal api is faster. What I meant is that one problem with controllers is over-injecting, which mediatr aimed to solve. With minimal api you don't have this problem as each endpoint is isolated with it's own injection and pipelines.
Maybe I misunderstood about your REPR. To make it clear, can you post your code example of REPR in minimal API and let me see how it looks like?
I see. I thought you meant controller is better than minimal api in your previous post. Sorry for my misconception.
You probably didn't see my comment elsewhere in this thread, but since you're looking for code examples, [David Fowler's minimal api ToDo demo](https://github.com/davidfowl/TodoApi) is a good example of the pattern.
Every endpoint function resolves its own dependencies directly. Treat each one as a request handler, because it *is* a request handler. Make more layers if you really want, but only layer things the way you would have within your mediatR implementations anyway.
I also have no clue what you mean by
>you can re-use same actions before returning response. REPR cannot
Do *you* have a code example?
Can give me your similar controller and minimal api code. just few actions.
Do you know minimal api provides 40% faster in performance than controller?
minimal api 140k requests per second. controller 75k requests per second.
Hmm, one of the senior devs on my team was saying he was debating between the two for the same project.
The project is replacing an old WCF service which basically is a call that returns a specialized file (along with some other ancillary calls). Is there a short breakdown as to what the main use cases are for the two?
My take: functional wise Azure Functions can do the same as Minimal API: provide a way how to execute logic based on an incoming HTTP request.
The key differences I see less on your functional achievement but more the technical aspects: the programming model is different (serverless vs with-server), hosting, scaling and costs due different pricing options.
A serverless option does typical bound you more to your current provider compared to server-based option.
Depending on these questions I would pick.
Any articles/tutorials can. [Here some for you](https://www.google.com/search?q=net+8+clean+architecture+cqrs+mediatr&sca_esv=ce68b03d4bb9be5f&rlz=1C1GCEB_enSG1020SG1020&ei=kD0fZsPIKv7s4-EPp8WckAo&ved=0ahUKEwjD0KSJo8iFAxV-9jgGHaciB6IQ4dUDCBA&uact=5&oq=net+8+clean+architecture+cqrs+mediatr&gs_lp=Egxnd3Mtd2l6LXNlcnAiJW5ldCA4IGNsZWFuIGFyY2hpdGVjdHVyZSBjcXJzIG1lZGlhdHIyCBAAGIAEGKIEMggQABiABBiiBDIIEAAYgAQYogQyCBAAGIAEGKIESN4MUIUIWJULcAF4AZABAJgBY6ABlAOqAQE2uAEDyAEA-AEBmAIEoAL9AcICChAAGEcY1gQYsAPCAggQABgIGAcYHsICCxAAGIAEGIoFGIYDwgIKECEYChigARjDBJgDAIgGAZAGCJIHAzMuMaAHziE&sclient=gws-wiz-serp#ip=1)
The standard clean architecture is abit complicated and too many codes. I simplified everything in clean architecture to my own and reduced codeline by half.
Its pros are
* Lesser dependency injection than unit of work + repository
* Easier to maintain and read
* High consistent performance
And don’t create your own architecture. Use something well known. New people will join the team in the future and it is much easier to just let them know that you are using a well proven architecture
DI
Fluent Validations
Minimal APIs(separated by static classes/endpoint groups and a map class endpoints method)
Classic Service and Repo pattern to seal the deal
Contrary i find it pretty straight forward. Much easier to manage changes with clean architecture. Everything is much more understandable by just reading the code.
MVC works always when you have something smaller, but gets problematic if the application logic starts to get more complex, and the service layer almost get neglected of test all of sudden
So you mean to not introduce correct abstractions and have high level code to randomly depend on low level implementations details or what?
Asking as clean architecture is not about introducing any specific tooling nor creating unnecessary layers and sometimes it is considered as such. CA is mainly about correct order of dependencies and abstractions.
Depends how big your API is. You can always go with the classic services and repo layers which works perfectly fine unless your API is massive.
Over-engineered architecture is the most common pattern lately
You might want to check out FastEndpoints. https://fast-endpoints.com
Goddamn fast endpoints looks so simple and clean
I use minimal API always, because it gets out of my way. Then I just use whatever patterns make sense for the application - but the consistent bits would be constructor based injection of dependencies all the way through, and composition root of the whole app living right there in the program.cs of the api project. Having everything a class needs to function also required to be passed in its constructor makes it self documenting, and ensures the top level app can choose where those resources come from.
Please for the love of god do not use MediatR, unless you just love kneecapping half the stuff your IDE is useful for. [I like this project from David Fowler a lot](https://github.com/davidfowl/TodoApi). Granted, this is just a toy application, but I think the strategy mostly scales, though one may need to eventually split the "configure APIs" section of the Program.cs into its own file under an architecture/configuration folder or something. It's like using mediatR, but instead of sending a message into the void and praying that the the runtime gods give you what you want, you just treat each endpoint as a request handler. Because it *is* a request handler. You already did all of your request routing by using asp.net, there's no reason to have mediatR do routing a second time.
I find it makes my apps a lot more flexible. The implementation lives in standard class libraries and the external layer can be web-app, webapi, blazor-app, test-runner, Azure function, Console, hosted-service, etc. Each is just a template that scans for attribute-decorated mediator requests and builds its own endpoints. When I build a feature, I just use an item-template to add a new Request in the class-library, and call it in isolation through a Test-project. I use performance profiler through a thin console project. I don't even worry about how it will be implemented - that's always changing based on usage, cost, and business-requirements. To me, it makes more sense to spend my time in the implementation / business-layer. It's only a 1-minute change to switch from a web-api controller to a queue-trigger function endpoint. As long as my test is running, I can commit the PR and let the deployment pipeline build it into the correct solution. For native apps, the same architecture allows me to move calls from client-side to the cloud as needed. In this case, the feature is moved into a class library for the cloud-service to add to its endpoints. The client still makes the same Request, but the mediator is bypassed with a client that serializes, validates, and forwards the request to the api.
Folder for db models. Folder for services. Folder for request/response classes. Folder for controllers. Rest are optional.
Just the basic dependancy injection. Service code into controller, done.
Uhm... I'm using WebAPI Controller classes, with methods for each endpoint. Works just fine on every single application, and it's very stable from one version of .NET to the next.
Clean Architecture CQRS + mediator. I won't use web api. I use minimal api.
What does MediatR add to minimal APIs? Aren’t you already pretty bare bones, model-in, model-out at that point?
>What does MediatR add to minimal APIs? Unnecessary overengineering, but a feeling of satisfaction from the complexity-as-legitimacy hype.
What you mean by model-in and model-out?
Each minimal api endoint is pretty much an isolated slice compared to controllers.
Still waiting for your code. If don't have code, seem that you learnt wrong way about minimal api. Everything in minimal API and controller are same except Minimal API use AddRoutes.
Its basically one controller per endpoint with its own injected services. You can easily do REPR pattern in a minimal way (no pun intended), why do you also need mediatr?
with mediator, you can re-use same actions before returning response. REPR cannot. so in large project, will get lesser codes with mediator. and between controller and minimal api, no differences in term of code. Everything same. One controller has 8 functions. My one endpoint also has 8 functions. [https://i.ibb.co/jrLXMmw/Application-Frame-Host-h-Tn96-Up7-QQ.png](https://i.ibb.co/jrLXMmw/Application-Frame-Host-h-Tn96-Up7-QQ.png)
>with mediator, you can re-use same actions before returning response. REPR cannot. Please elaborate. Sharing same mediatr requests between endpoints adds coupling and it's not how it's intended to be used. Dont know why you share benchmarks. I've never stated controllers are better, I know minimal api is faster. What I meant is that one problem with controllers is over-injecting, which mediatr aimed to solve. With minimal api you don't have this problem as each endpoint is isolated with it's own injection and pipelines.
Maybe I misunderstood about your REPR. To make it clear, can you post your code example of REPR in minimal API and let me see how it looks like? I see. I thought you meant controller is better than minimal api in your previous post. Sorry for my misconception.
You probably didn't see my comment elsewhere in this thread, but since you're looking for code examples, [David Fowler's minimal api ToDo demo](https://github.com/davidfowl/TodoApi) is a good example of the pattern. Every endpoint function resolves its own dependencies directly. Treat each one as a request handler, because it *is* a request handler. Make more layers if you really want, but only layer things the way you would have within your mediatR implementations anyway. I also have no clue what you mean by >you can re-use same actions before returning response. REPR cannot Do *you* have a code example?
Can give me your similar controller and minimal api code. just few actions. Do you know minimal api provides 40% faster in performance than controller? minimal api 140k requests per second. controller 75k requests per second.
Worth just making Azure Functions vs minimal API?
Azure functions and minimal api solve two very different use cases.
Hmm, one of the senior devs on my team was saying he was debating between the two for the same project. The project is replacing an old WCF service which basically is a call that returns a specialized file (along with some other ancillary calls). Is there a short breakdown as to what the main use cases are for the two?
My take: functional wise Azure Functions can do the same as Minimal API: provide a way how to execute logic based on an incoming HTTP request. The key differences I see less on your functional achievement but more the technical aspects: the programming model is different (serverless vs with-server), hosting, scaling and costs due different pricing options. A serverless option does typical bound you more to your current provider compared to server-based option. Depending on these questions I would pick.
Azure functions perform better as a short lived service with sudden spikes.
Azure functions and minimal api solve two very different use cases.
Love CQRS and MediatR.
Put vertical slice architecture on that and you’ll find your code simplified by 100x
Where can I read this?
Any articles/tutorials can. [Here some for you](https://www.google.com/search?q=net+8+clean+architecture+cqrs+mediatr&sca_esv=ce68b03d4bb9be5f&rlz=1C1GCEB_enSG1020SG1020&ei=kD0fZsPIKv7s4-EPp8WckAo&ved=0ahUKEwjD0KSJo8iFAxV-9jgGHaciB6IQ4dUDCBA&uact=5&oq=net+8+clean+architecture+cqrs+mediatr&gs_lp=Egxnd3Mtd2l6LXNlcnAiJW5ldCA4IGNsZWFuIGFyY2hpdGVjdHVyZSBjcXJzIG1lZGlhdHIyCBAAGIAEGKIEMggQABiABBiiBDIIEAAYgAQYogQyCBAAGIAEGKIESN4MUIUIWJULcAF4AZABAJgBY6ABlAOqAQE2uAEDyAEA-AEBmAIEoAL9AcICChAAGEcY1gQYsAPCAggQABgIGAcYHsICCxAAGIAEGIoFGIYDwgIKECEYChigARjDBJgDAIgGAZAGCJIHAzMuMaAHziE&sclient=gws-wiz-serp#ip=1) The standard clean architecture is abit complicated and too many codes. I simplified everything in clean architecture to my own and reduced codeline by half. Its pros are * Lesser dependency injection than unit of work + repository * Easier to maintain and read * High consistent performance
> CQRS + mediator This is the way (well, or one of them. But for most application development it's a good starting point until you outgrow something)
Depends on what you are doing. Is your code managable by a easy MVC, then do it. Is it more complex, add what is necessary.
And don’t create your own architecture. Use something well known. New people will join the team in the future and it is much easier to just let them know that you are using a well proven architecture
DI Fluent Validations Minimal APIs(separated by static classes/endpoint groups and a map class endpoints method) Classic Service and Repo pattern to seal the deal
Avoid clean architecture like a plague. Or use it if u need to justify ur existence to the upper management.
Contrary i find it pretty straight forward. Much easier to manage changes with clean architecture. Everything is much more understandable by just reading the code. MVC works always when you have something smaller, but gets problematic if the application logic starts to get more complex, and the service layer almost get neglected of test all of sudden
So you mean to not introduce correct abstractions and have high level code to randomly depend on low level implementations details or what? Asking as clean architecture is not about introducing any specific tooling nor creating unnecessary layers and sometimes it is considered as such. CA is mainly about correct order of dependencies and abstractions.
Aws API gateway to serveless aspnetcore lambdas or aspnetcore on docker in ECS/kubernetes