No video

Clean up your .NET Controllers with ApiEndpoints

  Рет қаралды 60,600

Nick Chapsas

Nick Chapsas

Күн бұрын

Check out my courses: dometrain.com
Become a Patreon and get source code access: / nickchapsas
Hello everybody I'm Nick and in this video I will show you an alternative way to build an elegant API in ASP.NET Core using ApiEndpoints, a nuget package created by Steve "ardalis" Smith.
Give ApiEndpoints a star on GitHub: github.com/ard...
Don't forget to comment, like and subscribe :)
Social Media:
Follow me on GitHub: bit.ly/ChapsasG...
Follow me on Twitter: bit.ly/ChapsasT...
Connect on LinkedIn: bit.ly/ChapsasL...
Keep coding merch: keepcoding.shop
#csharp #dotnet #apiendpoints

Пікірлер: 149
@Sirozha1337
@Sirozha1337 2 жыл бұрын
Great video as always! Want to note something for those who're struggling with controllers having too many dependencies. There's this useful attribute [FromServices], that will allow you to inject only the required dependencies in your controller method, e.g.: public PicturesController(ILogger logger){ } public IActionResult GetPictures([FromServices] IDatabaseService databaseService){ return Ok(databaseService.GetPictures()); } public IActionResult UploadPicture([FromForm] IFormFile file, [FromServices] IPictureService pictureService){ return Ok(pictureService.Upload(file)); }
@Dimonina
@Dimonina 2 жыл бұрын
We've been using Ardalis Endpoints for a year+ and pretty happy with it. Every method has its own "pipe". It means I don't don't touch the methods whose logic hasn't changed and I can see clear dependencies for each endpoind. It's much better than the controller, which usually has tons of dependencies and it's not easy to understand what depends on what after some time. Thanks for the video, now I'm more confident that we made a right chose.
@larryd9577
@larryd9577 2 жыл бұрын
I don't see what it delivers except of separation of each method from the one domain controller in each own little controller. Actually it is a lot of duplicate code. Id rather introduce an usecase specific ApplicationService in between the controller- and the server-layer.
@Sife-db
@Sife-db 2 жыл бұрын
I have same thoughts!
@jcorrify
@jcorrify 2 жыл бұрын
ApiEndpoints is built on top of mvc controllers, it would be nice to have a comparative with FastEndpoints that is built on top of C# minimal apis
@nickchapsas
@nickchapsas 2 жыл бұрын
No spoilers!
@nickchapsas
@nickchapsas 2 жыл бұрын
@@HagobSaldadianSmeik Have they? I thought they are using the Nuget package as a dependency. As far as I can see in the docs for FastEndpoints there is propery attribution to FluentValidation and the code in the validation project uses Apache 2.0 so technically the creator has done nothing wrong. I would prefer if they were just using proper FV so I don't have any conflicts in projects that might refer to both
@duznt-xizt
@duznt-xizt 2 жыл бұрын
@@nickchapsas I believe some frameworks like ServiceStack does the same thing. Conflicts may not be an issue since the namespaces would be different right? Not sure though.
@p3rcey
@p3rcey 2 жыл бұрын
so basically we want apiendpoints but built on minimal APIs - that's the dream
@nickchapsas
@nickchapsas 2 жыл бұрын
@@p3rcey We got it now. Check my latest video
@zoran123456
@zoran123456 2 жыл бұрын
NO! Let us not find the solutions for the problems that do not exist. But other than that, this was really well made explanation of a (not needed) package. Loved watching it.
@PticostaricaGS
@PticostaricaGS 2 жыл бұрын
Totally agree with you, it only complicates things unnecessarily
@duznt-xizt
@duznt-xizt 2 жыл бұрын
The main problem this solves is controllers tend to get bloated in the longrun and gets cluttered by too many unrelated dependency injections. I personally never liked controller approach and this seems more natural to me. In the end, whatever that rocks your boat eh! ;-)
@liquidvapour
@liquidvapour 2 жыл бұрын
Would be great to show how "testable" a new framework is when demoing it. Keep up the good work.
@peopleofourtime2523
@peopleofourtime2523 2 жыл бұрын
What I really like about your videos is that when they are opinionated, you point out that it is opinionated and that there are other ways of doing this that people may prefer. So many KZbinrs don't do this and it frustrates me and leads me to think that they are purposefully biased and misleading.
@nickchapsas
@nickchapsas 2 жыл бұрын
I think I approach such topics in a way that I would like them approached if someone is explaining them to me. Nothing is perfect and acknowledging shortcoming and suggesting alternatives is always a good thing. I’m usually very worried when people are dogmatic about a topic
@PoetNoPoems
@PoetNoPoems 2 жыл бұрын
I looked at this ApiEndpoints library and then I thought, well based on the nice isolation of this approach why not just skip both the ApiEndpoints and Mediatr and just have your Controller, Request and Response Dtos in a single folder. Your controller only has one endpoint (Action Result) and only has injected services it uses, and it all looks like you generic controller but you don’t have any dependencies just plain old .net stuff. With this approach I got rid of Mediatr which although pushed things from my controller nicely, I still had one controller with many endpoints (Action Results). You don’t only have to have controller in a web project because its just a nuget package and with custom routing you can keep all customer related endpoints under the same [controller]/[action] style but there all in their own folders following the slice architecture patter quite nicely too. Been working for me for a few months now so quite happy
@giovani5586
@giovani5586 2 жыл бұрын
how do you manage to test it? any code example?
@PoetNoPoems
@PoetNoPoems 2 жыл бұрын
@@giovani5586 well its just a normal controller so you just write your tests as you would on a controller with many action results and their accompanying functions...I hope i am not misunderstanding your question
@PoetNoPoems
@PoetNoPoems 2 жыл бұрын
One thing I do suggest on this approach is to have a static route and endpoint provider to have all the names of you routes and endpoints as you wont have a god controller which requires different names
@Albileon
@Albileon 2 жыл бұрын
I could maybe misunderstand the problem this project is trying to solve, but if you want to split up your controller to have cleaner code, couldn't you just create partial classes with each their own file name in a folder?
@nickchapsas
@nickchapsas 2 жыл бұрын
Because it's not only about logic isolation but also physical. You don't have to worry about conflicting attributes on both controller and action level. I also dislike controllers as an idea all together so the complete logical separation from then is really attractive to me
@Albileon
@Albileon 2 жыл бұрын
@@nickchapsas Alright fair enough
@lolyasuo1235
@lolyasuo1235 2 жыл бұрын
@@nickchapsas This approach would be definitely good approach for apps with many and complex filters
@Lammot
@Lammot 2 жыл бұрын
@@nickchapsas Which conflicts are you talking about? Aren't you bound to make more mistakes just because you now need to be more explicit about routes, for example?
@iWhacko
@iWhacko 2 жыл бұрын
@@nickchapsas No, but you should still have a controller layer. so endpoint > controller > service > data Because businesslogic should not be in an endpoint
@vorontsovru270895
@vorontsovru270895 2 жыл бұрын
Damn, I literally stumbled across the repository of this project today and here is your video XD
@seephor
@seephor 2 жыл бұрын
I don't see this package that much more elegant than the current controller architecture out of the box. The only real thing you gain here is a little better code structure.
@rvladkent
@rvladkent 2 жыл бұрын
Interesting library, but at the end of the day it all depends on the agreements in the team. Usually What worked for my projects is separating write endpoints to their separate write controller and read controller
@OnurBuyukcaglar
@OnurBuyukcaglar 2 жыл бұрын
@Nick Chapsas, thank you for your great content. It would be amazing if you tell us how would this scenario fit in Clean Architecture, in your own perspective. Because it looks like, if we utilize this approach and get rid of so-called "unnecessary" abstractions such as MediatR, CQRS, Repository etc. then we almost would not need Application Layer altogether (aside from definition (Interfaces) of services and DTO Models) since implementation of services done in Infrastructure Layer in Clean Architecture.
@tuberklz
@tuberklz 2 жыл бұрын
this similar mindset with mediator pattern maybe would be very useful when working on a complicated legacy project where you would step by step recreate into an app. again, thanks for sharing
@ifeanyii353
@ifeanyii353 2 жыл бұрын
Notification gang! Black coffee and Nick sharing generously is a sweet combo
@MauricioSierra
@MauricioSierra 2 жыл бұрын
Very similar to a serverless approach. Nice I like it
@vifvrTtb0vmFtbyrM_Q
@vifvrTtb0vmFtbyrM_Q 2 жыл бұрын
Well, what can I say, first we make difficulties for ourselves and then we heroically defeat them.
@AJax2012
@AJax2012 2 жыл бұрын
You and Steve are probably my favorite .NET content creators/instructors. I've learned so much from both of you over the past few years. Great work, both of you!
@csabraxas
@csabraxas 2 жыл бұрын
Steve? Share link?
@kostasgkoutis8534
@kostasgkoutis8534 2 жыл бұрын
@@csabraxas Steve Smith a.k.a Ardalis
@alphaprimal1669
@alphaprimal1669 2 жыл бұрын
Nick here demonstrating compiler Boostrapping by creating him by him as an example jk. Nice Video Thank you
@thiagocustodio8177
@thiagocustodio8177 2 жыл бұрын
in the past I used to split controller actions using partial classes which would help a lot merge conflicts and keep things organized. I didn't know about this template, I will give it a try in my next projects. Thanks for sharing
@I-PixALbI4-I
@I-PixALbI4-I 2 жыл бұрын
Next video is Services vs MediatR vs ApiEndpoints )
@josephizang6187
@josephizang6187 2 жыл бұрын
Man, Nick you rock. I will definitely check this out.
@lordicemaniac
@lordicemaniac 2 жыл бұрын
I especially liked that type BaseAsyncEndpoint.WithoutRequest.WithResponse. If I understand this correctly, then BseAsyncEndpoint class, probably does not have any attributes or methods but have subclasses such as WithoutRequest which have subclass WithResponse which finally contains code, all parents are probably just names to make code readable. Have to try this sometimes, I'm pretty sure there were many times when i had classes that inherited some base class and all were name SomeBaseClassWithSomething.
@Mike-qg1we
@Mike-qg1we 2 жыл бұрын
This looks very similar to Azure Functions where you have a class for each azure function that works as a form of 'controller'
@Reellron
@Reellron 5 ай бұрын
What is the advantage of using this instead of dividing a controller up in multiple files using the partial keyword, where you can have one file for Base, Get, GetAll, Update etc?
@DanielTabuenca
@DanielTabuenca 2 жыл бұрын
I'm not sure I understand the point of this. How is this different than just introducing multiple small single-purpose controllers?
@Luismvm90
@Luismvm90 2 жыл бұрын
I wonder what problems this actually solve, if your controllers are too complex and large, the problem is not the controller is it? This is just a different way of wrapping your code in my opinion, more of a preference than a solution to something.
@nickchapsas
@nickchapsas 2 жыл бұрын
It’s not about the controller complexity. It is about single responsibility and also not needing the Controller concept in the first place. Are you using MVC? No, it’s just a remnant of the pattern but in the context of an API it doesn’t make much sense.
@Luismvm90
@Luismvm90 2 жыл бұрын
@@nickchapsas I understand what your argument is, but the pattern is defined by the framework and this library just wraps that pattern in a different casing... It still uses MVC under the hood because that's how the framework works. So if anything, in my view it just adds noise breaking what the industry standard is for API development in .net core regardless of you agreeing with the pattern or not. Not following said standard in the enterprise world costs money training and educating people, as well as enforcing different practices that people aren't used to work with takes time and causes conflict. We'll have to agree to disagree on this one 😊
@nickchapsas
@nickchapsas 2 жыл бұрын
​@@Luismvm90 That's not true. The pattern is defined by you. We just chose to use the remnants of a pattern that is irrelevant to use because we get routing and filters out of the box with it. It isn't really a pattern as much as it is a means to get our code called. Same reaon why I prefer Minimal APIs over controller. Because it just ditches this outdated idea and goes straight for the endpoint.
@MiladPP
@MiladPP 2 жыл бұрын
What prevents you from creating multiple controllers? you're using the attribute route anyway. You can just create those controllers and just put the action methods you want there.
@nickchapsas
@nickchapsas 2 жыл бұрын
Nothing prevets you but that doesn't mean you should do when you have a better alternative. We are using Controllers because that's how routing was done in MVC but in the context of an API they are just the entry point. Contextualizing the entry point in a coheasive pipeline, even if what you're doing in hiding the underlying controller call and adding generic constraints, offers a better experience
@mohammadazhdari4469
@mohammadazhdari4469 2 жыл бұрын
Despite partial controllers which solve some of issues mentioned in this video, why not creating a separate controller for every action? It needs same amount of work, without dealing with another package.
@nickchapsas
@nickchapsas 2 жыл бұрын
But why? What does the controller add in the context of my application? What does it mean? The endpoint naming and constraints make it very clear. You are creating an "Api Endpoint", which accepts "this request" and returns "this response". It's meaninful. A controller can mean anything and we only know what it means because of it being an MVC artifact.
@Sirozha1337
@Sirozha1337 2 жыл бұрын
@@nickchapsas Well you can create a base Controller: "Endpoint : ControllerBase" and use inheritance to force these constraints, but that's just reimplementing what this library already does.
@iantabron
@iantabron 2 жыл бұрын
@@nickchapsas whilst I quite like the idea behind this library, I think it is just substituting the parameter and return type constraints of a regular Web API Controller action with class-level type constraints; which don't actually constrain you more than the former. The main benefit you are demonstrating is the separation of CRUD responsibilities which, in theory sounds good, but means you now have five classes to maintain that all consume the same service-level dependency, instead of one. I'm undecided on whether this is beneficial or not. I currently work with a legacy framework that is built around the CQRS pattern, and this library would nicely extend the CQRS pattern to an API layer given that CQRS roughly provides the same concern separation out of the box. I'm just not convinced that the end result is either clearer or more maintainable.
@Sife-db
@Sife-db 2 жыл бұрын
@@nickchapsas I think you may rename Controller sufix to whatever you want))
@oleksandrkulchytskyi5970
@oleksandrkulchytskyi5970 2 жыл бұрын
Thank you for sharing that with us!
@microtech2448
@microtech2448 2 жыл бұрын
Doesn't seem solving problem. It will require lot of code to be written.
@chrisowens6670
@chrisowens6670 2 жыл бұрын
Actually less code.
@haraheiquedossantos4283
@haraheiquedossantos4283 Жыл бұрын
Which one is better: APIEndpoints or FaatEndpoints?
@Kingside88
@Kingside88 2 жыл бұрын
On this approach I have so much more to write. By the way you look a little bit tired. maybe you need to see the sun more often 🙂
@nickchapsas
@nickchapsas 2 жыл бұрын
You’re implementing single responsibility and open-closed in a much better way than controllers. Don’t try to put this into perspective with CQRS and MediatR. Just forget that controllers exist and look at it objectively. One class, per endpoint with its own boundaries, responsibilities and dependencies. It only looks weird because you are used in something different
@mehdihadeli
@mehdihadeli 2 жыл бұрын
Thanks for your video, When should we use minimal API and when API Endpoint? Maybe for some situation like versioning or full swagger documentation support that minimal API doesn't support currently, we should use ApiEndpoint. Though?
@nickchapsas
@nickchapsas 2 жыл бұрын
I personalyl prefer Minimal APIs over Controllers and APIEndpoints but I also like FastEndpoints which is trying to achieve the same thing as ApiEndpoints but with minimal APIs backing it instead
@mehdihadeli
@mehdihadeli 2 жыл бұрын
@@nickchapsasThanks, Could you create a video for limitations of minimal api like versioning, swagger documentation, …?
@duznt-xizt
@duznt-xizt 2 жыл бұрын
@@mehdihadeli You forgot the biggest annoyance with Minimal Api, which is requring us to manually map each and every endpoint in startup, unless you wanna write your own assembly scanner. Like nick mentioned above, FastEndpoints seem to be doing a good job by giving us best of both worlds.
@TheSysmat
@TheSysmat 2 жыл бұрын
Open Api is much better for endpoint doc or generating client
@computer9764
@computer9764 2 жыл бұрын
Looking at all those classes with the DI makes me want Blazor style [Inject] attributes. I have mixed feelings about so many classes. Maybe it will be easier to parse when C# gets file-scoped classes, but I feel like more files adds more cognitive load than having longer files.
@steve-ardalis-smith
@steve-ardalis-smith 2 жыл бұрын
More files makes for far fewer merge conflicts and much easier for teams to collaborate, among other benefits. But yes, some folks prefer scrolling to separate files, I acknowledge.
@evancombs5159
@evancombs5159 2 жыл бұрын
The number of files isn't want increases or decreases cognitive load. It is the organization of your project. It only seems like the number of files increases cognitive load because the standard project organization methods of the last 20+ years increases cognitive load the more files you have. If you switch up your organization method to be more feature based the number of files you have has essentially no affect on cognitive load as you everything related to each other , and only things related to each other, are in the same folder. With this method of organization cognitive load is more about folder structure than file count.
@microtech2448
@microtech2448 11 ай бұрын
Not convinced, that is more weird. In name of separation increasing code duplicacy and complexity and depending on pray of the third party library.
@daniildoronkin2959
@daniildoronkin2959 2 жыл бұрын
Nice approach! I had pretty same feelings about using MediatR instead of the classic application services - you can separate responsibilities even cleaner and simpler.
@aleksandrpiskunov7124
@aleksandrpiskunov7124 2 жыл бұрын
As I see, the MediarR does the same thing: you only have one dependency in a controller class. What’s the purpose to split up the controller in separate classes, one per endpoint? Or maybe this library is supposed to be an alternative to the MediatR?
@nickchapsas
@nickchapsas 2 жыл бұрын
Yeah I’d say you don’t need MediatR with this. I would argue you don’t need it at all but yeah, this does the separation by default
@tafs7
@tafs7 2 жыл бұрын
As @nick said, you don't need mediatr with this. However, one gotcha is that your web endpoints become your command/query types but still have dependencies on a web framework. If that's not a problem for your architecture, then use this. However, if you need an application layer that is fully decoupled from any web framework dependencies, mediatr enables that better. Basically, you'd have two csproj, one being an aspnet project and the other a class lib project.
@tafs7
@tafs7 2 жыл бұрын
@@svorskemattias I never said you needed mediatr with either. Just pointing out where mediatr fits well, but not required.
@zbaktube
@zbaktube Жыл бұрын
What is the overhead on the "override", and in general on this EndPoint mechanism?
@NealAnthoons
@NealAnthoons 2 жыл бұрын
Great video! Was just wondering what font you use ?
@hakanaltindis
@hakanaltindis 2 жыл бұрын
I did not like this package too much. Because if I choose to use this way, I will write more code. But I prefer to write less code always. But thanks for your share
@thienan2672
@thienan2672 2 жыл бұрын
I encountered a problem: I want to create an abstract endpoint, with some crossing-cutting concerns like getting a userId from the Claims. how can I do this? It seems like inheriting from the EndPointBase is not possible
@sommmen
@sommmen 2 жыл бұрын
How'd you go about deduping common endpoints? For ex. We have lots of controllers that have a default GET class. This resides in the base class and is used 80% of the time. We call it with a request object which can filter/order/sort/search etc. How would this look for multiple (business/db) entities?
@eugenesukharev5871
@eugenesukharev5871 2 жыл бұрын
Nick, Like then Watch 🙂👍
@raphaelmt1706
@raphaelmt1706 2 жыл бұрын
I've been going more and more in the direction of having a separate handler for each request and this is very cool. The only thing right now which makes me stick with controllers is that I have a two-layered C# application and so I started using Refit to generate the http clients from an interface implemented by the controller. This makes the inter-layer communication a lot more transparent and type-safe. I'm curious if someone has suggestions to have this kind of type-safe strong contract while moving in the direction of separate endpoints like this example or minimal APIs.
@duznt-xizt
@duznt-xizt 2 жыл бұрын
NSwag can generate strongly-typed http clients from a swagger document.
@raphaelmt1706
@raphaelmt1706 2 жыл бұрын
@@duznt-xizt will look into that thanks
@Psykorr
@Psykorr 2 жыл бұрын
Ok so basically its one controller per method. Only it's made to look more complicated. I know that it is considered "clean" to have many small files but I really do not like getting into a codebase and there are thousands of files. I really do NOT hope they have started this practice when I come back to work. Terrible! It does not solve any problems it just introduces another abstraction layer for no reason, it does not add security, it does not make the program more modular, it does not make the code more ledgible - in fact it just makes it more annoying to read the code. Somebody thought it was difficult to know which method are using what dependency in a normal controller, well I guess they forgot to just look at the method! Ffs. No, this is useless imo. No offence :) I like this channel.
@nickchapsas
@nickchapsas 2 жыл бұрын
Well I disagree with many of the things you don’t think the library is doing, and I think it all stems from thinking about it as a controller. Why do you think people use MediatR? It doesn’t introduce a layer of abstraction, it’s just another way to route a request to a place to handle that request and it keeps the scope small. It helps you implement single responsibility and open-closed. If you think that it’s annoying to keep your classes small and targeted to one specific thing then you might wanna rethink how you right your code.
@Psykorr
@Psykorr 2 жыл бұрын
@@nickchapsas I used to be all into that kind of thing with classes and so on and I have actually rethought how I code, well privatly at work you just code how ever the company wants any way, and moved away from that enterprice way of coding and thinking about code. I did not try to insult you or insinuate that there is something wrong with how you write code. This is only a matter of opponion. I follow you for the consistent and good quality content, once in a while though I just don't agree 100% :)
@geomorillo
@geomorillo 2 жыл бұрын
i agree totally i was watching and thinking wtf? why complicate things?
@chrisowens6670
@chrisowens6670 2 жыл бұрын
It makes the code significantly more readable since it's only dealing with a single concern. Some people just like scrolling through bloated classes with thousands of lines I guess...
@Psykorr
@Psykorr 2 жыл бұрын
@@chrisowens6670 haha yes because it has to be either a few lines per class and file, or it has to be only one class with thousands and thousands of lines of code. There is no middle ground, right? There are many ways to organize code you know. You do your thing, let me do mine. Sheeesh.
@SergeiCalabonga
@SergeiCalabonga 2 жыл бұрын
Thank you. A Controller can contain only one method and in this way it looks like Endpoint. :)
@nikola7377
@nikola7377 2 жыл бұрын
Wouldn't we end up with too many classes like this
@nickchapsas
@nickchapsas 2 жыл бұрын
Why is that a bad thing? You should be worried seeing too little classes because usually they are an indicator of violating single responsibility
@evancombs5159
@evancombs5159 2 жыл бұрын
Only if you use poor organization practices. If you use a vertical slice organization approach the number of classes is mostly irrelevant as you will mainly be working with folders for navigating to files. Within each folder there will be a minimal amount of files only relevant to the feature you are working on.
@clashclan4739
@clashclan4739 2 жыл бұрын
Appreciate your efforts. But there is already a lot to cover which is already there with no in depth understanding. Can u pls focus on security features should be followed in asp.net core with angular applications
@Quique-sz4uj
@Quique-sz4uj 2 жыл бұрын
Nice video! Does your Rider work fine with top level namespaces? Without braces and all of that? Because mine gives Errors
@nickchapsas
@nickchapsas 2 жыл бұрын
Yeah it works fine. You might be in an old version
@DanWalshTV
@DanWalshTV 2 жыл бұрын
I believe they added top-level namespace support in version 2021.3.1 - Check which version you're running
@MagicCPM
@MagicCPM 2 жыл бұрын
Does it can handle sagger page? if so, how? just installing Swashbuckle as usual?
@MagicCPM
@MagicCPM 2 жыл бұрын
Ok, I saw the end of the video... great :)
@expertdevs
@expertdevs 2 жыл бұрын
Very useful, 👍
@proftproft3404
@proftproft3404 2 жыл бұрын
Try Cypress instead of Postman ;)
@timothywestern6488
@timothywestern6488 2 жыл бұрын
Why not one CustomerEndpoint class and each of the methods its own method in that? I don't get what you really buy with a separate file for each method except to see this layout from the file tree (you could use something like object viewer to see something similar)
@steve-ardalis-smith
@steve-ardalis-smith 2 жыл бұрын
Better following of SOLID principles, fewer merge conflicts, easier for different team members to work at the same time on different endpoints, easier to associate individual request/response types with each endpoint (Nick didn't show this but they're grouped with the endpoints in the solution explorer in Visual Studio, for instance).
@timothywestern6488
@timothywestern6488 2 жыл бұрын
@@steve-ardalis-smith the merge question is an interesting one. It may depend on just how wordy a given endpoint is I suppose. but I'll be honest, I find this approach just looks messy. I am in favor of not calling the services directly in the controller, but passing them into an endpoint that then manages them however. SOLID is great, but the more files you have the more places you have to look at changes potentially. I have yet to run into a place where multiple engineers would be making changes to the same endpoint at the same time. I do know it happens in other layers a lot though, especially those danged controllers. I may eventually come to agree with you, if I was working on larger projects though. I'll keep this in mind.
@aliahmadi3902
@aliahmadi3902 2 жыл бұрын
This is good idea, but in practice this is make complexity in endpoints , I prefer use something simple. "KISS" Thanks
@nickchapsas
@nickchapsas 2 жыл бұрын
This is actually KISS. A controller tends to not be because it involves multiple injections for multiple services you might not need and filters
@ugochukwuumerie6378
@ugochukwuumerie6378 2 жыл бұрын
@@nickchapsas does lazy loading the services work? I have seen examples online where they lazy. Tech is crazy
@nagasudhirpulla
@nagasudhirpulla 2 жыл бұрын
I searched the meaning of pragmatic and dogmatic while watching this video 😂
@MarkTrudgeonRulez
@MarkTrudgeonRulez 2 жыл бұрын
I assume the Authorized attribute still works
@nickchapsas
@nickchapsas 2 жыл бұрын
Every attribute that works for the controller still works on this
@vadymwork3983
@vadymwork3983 2 жыл бұрын
What sources do you use to learn all these practices?
@nickchapsas
@nickchapsas 2 жыл бұрын
I just try out things and check what, people I follow, like Steve, are working on
@myuuiii
@myuuiii 2 жыл бұрын
Notification Squad
@the-avid-engineer
@the-avid-engineer 2 жыл бұрын
Since when does `new[]{…}` work in an attribute? O.O
@octaviandobre
@octaviandobre 2 жыл бұрын
Any benchmarks for this library ?
@nickchapsas
@nickchapsas 2 жыл бұрын
I intentionally didn't add them because it is just a controller behind the scenes so it performs exactly the same
@ibnfpv
@ibnfpv 2 жыл бұрын
Great , but I think with mediator this way does not bringing any benefit as the mediator will redirect you to the relevant service handler with the relevant dependencies.
@nickchapsas
@nickchapsas 2 жыл бұрын
Don't use MediatR then. You don't need it anymore
@ibnfpv
@ibnfpv 2 жыл бұрын
@@nickchapsas but the benefit it the mediator in my opinion in compare is that the handler can be in lower level And not part of the api level that is much higher Here the handler is an controller something you not put in a class lib lower level project in the solution structure The lower level benefit is that you put the BL in that layer and decouple it from The api level
@chrisowens6670
@chrisowens6670 2 жыл бұрын
MediatR still has a place in resolving dependencies to common services or cross-cutting concerns with this approach if you want to use it. It also allows in-process messaging via Publish and the behavior pipelines (and is easier to set up than other libraries). I like this for some things, and mediatR for others...
@scdecade
@scdecade 2 жыл бұрын
Procedural programming of relational data is obsolete. All of this code can be (and is better) generated from the database model. No need for MVC anymore either.
@lolyasuo1235
@lolyasuo1235 2 жыл бұрын
Imagine combining this with CQRS + Services layer + Repository + Unit of Work + Anything else... ohhh too much abstraction. Im not sure if i like the idea of having multiple classes/apiendpoints for every action method. The code navigation would be nightmare. On the other hand having fat controllers with all api endpoints per domain object is a big chaos. So i don't know, i can't say anything. i would like to see this in more advanced scenarios.
@nickchapsas
@nickchapsas 2 жыл бұрын
It actually ends up being way simpler in my opinion because you just have that one class to deal with. You don't need MediatR, CQRS or the Repository pattern. Just cut on pointless abstractions and you'll see that this is more manageable
@steve-ardalis-smith
@steve-ardalis-smith 2 жыл бұрын
@@nickchapsas Exactly. Many projects that use MediatR today to try to keep their controllers slim could use this approach without the indirection MediatR adds.
@nickchapsas
@nickchapsas 2 жыл бұрын
@@svorskemattias What is CQRS? It isn't MediatR. The endpoint part is part of the CQRS journey. Starting in complete isolation from the api layer all the way to the database layer given a significantly clearer segregations. With controllers you are using MediatR to add this middle layer that does the clear separation for you, but it's a lie because it is a limitation of the Controller
@lolyasuo1235
@lolyasuo1235 2 жыл бұрын
@@nickchapsas Yea this looks good. Just ApiEndpoints + EF. I like this.
@nickchapsas
@nickchapsas 2 жыл бұрын
@@svorskemattias It doesn't need to replace any, but it is a better implementation if you are going to do CRQS :)
@camelpilot
@camelpilot Жыл бұрын
So bad. More code, more complexity, less organized and harder to test.
@faximori
@faximori 2 жыл бұрын
Repetitive and additive code without any benefit. Would be nice to achieve some things with one line, not many.
@papamoneyph
@papamoneyph 2 жыл бұрын
one class for one api call?? with a large project, this would produce hundreds or thousands of classes… why??
@nickchapsas
@nickchapsas 2 жыл бұрын
What’s the alternative you are using? One large controller that injects multiple services used by multiple endpoints? Does that controller have more the one reason to change? I bet it has since you have more than one action.
@papamoneyph
@papamoneyph 2 жыл бұрын
@@nickchapsas unfortunately, that is the case
@Andy-si1pl
@Andy-si1pl 8 ай бұрын
​@@nickchapsas a large controller can be easily split into two - grouping logical parts together AccountController - create account - reset password - register - change password ShopController - create order - modify order If a creation of an order involves a new customer, extract the create process from AccountController.createAccount so that it can be consumed by ShopController.CreateOrder AND AccountController.createAccount. It would sit in a diiferent Shared folder. What is wrong with that???
@asdasddas100
@asdasddas100 2 жыл бұрын
So this is just another way of doing CQRS?
@nickchapsas
@nickchapsas 2 жыл бұрын
Nop. This is just an implementation of single responsibility for your endpoints.
@PticostaricaGS
@PticostaricaGS 2 жыл бұрын
One of our customers use this, I heavily dislike it tho, this approach has the downside of terrible long names for clases and file names, additionally this approach makes development slower and makes it more expensive for the customers
@duznt-xizt
@duznt-xizt 2 жыл бұрын
Yeah I agree that long class names are kinda offputting but, My experience has been nothing short of a miracle after going "Endpoint per Action" or as Steve Smith puts it, REPR pattern. It really helps maintain complex projects in the longrun specially if you combine it with Vertical Slice Architecture.
@chrisowens6670
@chrisowens6670 2 жыл бұрын
How does it make it slower and more expensive? Separation based on requests supports SOLID principles, and makes changes easier since they only affect that one operation. Also longer more clarifying names is better. I never understood why developers feel the need to abbreviate so much when they never agree on the abbreviation to use. I got into brownfield systems with CrashID, CrashNumber, CrashNum, CrashNbr, CrashNmb, CrashNumId, etc... - all in the same system. I make all my developers spell things out now.
@teemuhellman9271
@teemuhellman9271 Жыл бұрын
Nowadays you can replace the annotations approach with Ardalis.ApiEndpoints.Swashbuckle nuget and add UseApiEndpoints to your SwaggerGenOptions
A new way to build CLEAN and FAST APIs in .NET
17:52
Nick Chapsas
Рет қаралды 92 М.
Don't throw exceptions in C#. Do this instead
18:13
Nick Chapsas
Рет қаралды 257 М.
Or is Harriet Quinn good? #cosplay#joker #Harriet Quinn
00:20
佐助与鸣人
Рет қаралды 14 МЛН
How I Did The SELF BENDING Spoon 😱🥄 #shorts
00:19
Wian
Рет қаралды 37 МЛН
When you discover a family secret
00:59
im_siowei
Рет қаралды 23 МЛН
Are events in C# even relevant anymore?
16:19
Nick Chapsas
Рет қаралды 168 М.
Making async code run faster in C#
10:28
Nick Chapsas
Рет қаралды 106 М.
High-performance logging in .NET, the proper way
15:56
Nick Chapsas
Рет қаралды 72 М.
How to write "smarter" enums in C#
12:56
Nick Chapsas
Рет қаралды 134 М.
8 await async mistakes that you SHOULD avoid in .NET
21:13
Nick Chapsas
Рет қаралды 312 М.
How to test your tests in .NET
11:05
Nick Chapsas
Рет қаралды 38 М.