C# ASP.NET 5 - Dependency Injection, RESTful Web APIs, Generating Swagger

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
[Music] [Applause] [Music] recording is running so we can switch to english again and in this third lesson of today's of today's morning we are going to build an asp.net core application we are going to build the event management that we started in swagger but this time we are going to implement it in asp.net core and i'm going to show you a lot of things which we haven't covered before with asp.net core so let's create a new project here we are going to implement an asp.net core web application as usual next and let's call it event management api you can call it whatever you want i will call it event management api good please select.net core web api as usual asp.net 5 it doesn't matter whether you use configure for https the only thing that i would definitely ask you to do is add open api support create let's put that here and with that we have a new api that's nothing special you have done that before you have done that in the last exam very well so yeah nothing special here as usual we are going to switch away from internet information server hint to our event management api to run it inside a console app so i think that's a better option it's easier to maintain if you ask me and the other thing that we are going to do we are going to delete two files we are going to delete that one and we are going to delete that one because that is auto generated sample code and i would like to show you step by step how we add a new controller and how we add the controller operations and things like that so please delete these two things first weather forecast dot cs let's get rid of it and here weather forecast controller deleted and it's gone please try to build your application it should build without any warnings without any errors it should just work i will give you a second to catch up good i assume you have now created or deleted the things everything builds correctly if you have any problems please interrupt me tell me that you need more time or ask your questions we are going to build an event management api and now for the first time we are going to do something which you always should do when you create some some kind of web api you should always separate your business logic or your data access logic from your api controllers i know up until now we accessed our entity framework classes directly from within our asp.net core controller methods we should not do that in practice we did that because we were just beginners we were just practicing and it's fine for beginners but now you are no longer just beginners you are more advanced users of asp.net core and therefore we are going to split we are going to separate our helper methods for business logic and data access into separate classes okay in many cases people call these classes services services because they are services within your application so what i'm going to do here is i'm going to oops i'm going to add a folder and call it services but that is just the name that i have chosen if you don't like services and you would like to call it data access or business logic or in a larger application maybe you don't have a single folder but you have certain topics and you create multiple files it doesn't matter it's just a place where you put your business logic your data access whatever just structure your project properly in these services we are going to add a very simple plain class typically we would now add some entity framework and modal classes but we want to keep everything simple here so therefore we are going to use just an in-memory representation of our event list so we are going to use just a list of t and skip the database for now the reason why i do that is because i want to keep the noise content ratio good we want to focus on asp.net core now but don't worry in the upcoming weeks we are going to bring together entity framework and asp.net core again but for now it's just in memory lists let's call it events repository or let's call it event repository events event oh we can discuss that i will call it events repository i like that name repository is just a name for a pattern that says here we can store events repository is a kind of name for a generic store of data okay you can call it whatever you want if you want to call it events store that's fine too but very frequently you hear the the class name repository for something that we do here now in this events repository we need to represent an event and in practice i would now do the following i would go to our where do i have it to our document here for instance uh let me see if i still have it um here yeah exactly i would take a look at this schema from my open api specification and then model my classes inside of my c sharp according to this schema so an event consists of an id of a date a location and let's add a description also so the specification is now the basis for our writing the code let's go back to the code here and modal the easiest thing would be a record let's model a record let's call it event and this event should have an integer id because here we have an integer id see it then we have a date time date because we have a date i think you get the idea now a string location and a string description okay do you absolutely have to use a record here no you don't you can also use a plain class a record is just a very uh very good and and elegant way of defining a data structure that has a constructor with which we can create it so a record is really a nice thing for a so-called data transfer object it's just an object which you use for storing some data and transferring it between services and things like that if you don't like records it's perfectly fine you can use a regular class and create an event and create all the different properties and so on and so on it's fine it's just up to you records are pretty new are a pretty new feature in c sharp and for web apis i really like to use them behind the scenes they are just uh a special form of class okay good now in this events repository we should not and do not care about the http protocol we do not care about how the events are represented on the network wire we just implement the necessary business logic or data access logic for storing and retrieving events this should be completely independent of any kind of web api it doesn't matter if that's a web api project or a full client api or a mobile app this repository implementation should always be the same so forget about asp.net core for now we will just implement the necessary operations for maintaining events what could that be public event add event new event that could be our first method we are adding an event and we are returning the event that we just added why do we return the event well maybe the event the new event here was changed in the course of adding it to the repository think back entity framework can you remember primary keys the primary key is zero before you call save changes and after you called save changes you magically get the primary key from the databases inserted in the data record if something happens like that we just return the same event with all the changes that happened during during adding the event to the data store okay that's just a convention many people do that and it's a good idea okay let's implement the event we have to store the events somewhere so let's create a private list of event this will be my events okay and let's just do [Music] a get operation here something like this and we can also create this thing immediately here this will just initiate initialize and declare a store for our events in real life let's comment it here in real life use ef core so in real life we don't have a list here but we'll have a data context and use the data context to access the underlying database but for our simple example we just use a list here now let's add the new event to the event event add new event and return new event in our case everything is unchanged we just returned the same object but i already told you if we would use entity framework then we would probably get a changed event back okay very simple operation next one let's add a method public public i innumerable of event get all return events to let's add a something like this we can even just return events here okay if you have a method like that you can simplify it to a great extent by using the expression syntax you can just write it like that i think i've shown you that before it's exactly the same it's just the shorter form you don't need the curly braces you don't need the return just a recap get all let's implement a public event get by id which takes an integer id and should return the id of the the uh sorry should you turn the event with the specified id so what we do is we say events dot first or default with event id equals id first or default is important the or default means that the method returns null if there is no event with the given id okay that means the or default if we would specify first and there is no id we get an exception i don't want to have that i just want to add no another tip here it is a kind of naming convention if you no forget it it's not that important i'm i'm losing track here it's fine like that it's perfectly fine like that okay so that is the get by id method so we have an add we have a get all we have a get by id and the last one i would like to say public void delete int id we want to delete something from here okay we can do the following we can say uh yep var event equals to get by id id id oh sorry event is a is a event to delete event is a reserved word in c-sharp so we are getting the event if event to delete equals null then we have a problem see it the problem is this id doesn't exist so let's throw an exception argument exception and in the argument exception here we can specify some come on i want to show in any sense here argument of course i'm sorry new argument exception we can specify a message and the parameter name so no event exists with the given id and the second parameter is the name of the parameter which was wrong which was which contained invalidator name of id otherwise we just say events dot remove event to delete get it so now we have add we have get all we have get by id and we have delete i will give you a second to enter this code let's make it a little bit smaller so it fits on the screen take sip from my coffee to give you time to catch up don't get me wrong this is not a professional implementation of an in-memory repository so this is not production code in real life you would have to write much more code because of course the http requests can run in parallel they can run at the same time you have to think about data races and and semaphores locking and protecting the list of events and things like that but that's not our topic here so our topic here is not implementing a perfect in-memory repository in real life we would we would use the database and the database was would care for that okay now today we want to focus on asp.net core so it's fine to build a repository like that it's very very simple and for your homework and implementation similar to that is okay because our core focus today is asp.net core not and i repeat myself not the implementation of a perfect in-memory repository does anybody need more time writing that code is it fine good that core that code is now completely independent of asp.net core and that's fine that is exactly what we want to have now let's switch gears and go to asp.net core let's add a controller right click on the controller add controller api empty controller go for it let's call it events controller why did i call it events controller well because here we specified that the path should be called events and we know if we take a look that here the controller name is injected into the path and therefore in this case if i want to fulfill the specification i call it events controller because again here it is you can choose a different name and then change just the name up here but at the end of the day you should fulfill the specification good now we have a problem because this events controller needs to have access to this events repository down here to this one how does the events controller gets get the events repository the most simple thing would be the following we can create a private member private events repository repository make it read only and generate the constructor where we just say repository equals new events repository we could do that but it's not good it's not considered good style this shouldn't be the way that you develop your professional apis why is that the case the reason is that our events controller here which implements the web api and the underlying business logic class or data access class is now tightly coupled you see it here they are bonded these two things they they can't be separated the events controller has hard coded that it needs and wants to use the events repository at one point in time you could say you know what let's add a second service let's call it database events repository with entity core entity framework core in the back end but then you have to change the events controller in order to make it using a different implementation of the repository if you want to write a unit test where you don't have this repository but you want to use a so-called mock object i'm pretty sure you've heard that term before mock object means you are just simulating the existence of a repository because during testing you don't have a physical database so you want to simulate the existence of a database that is called a mock object it's not possible here because the events controller is hard coded to use the events repository so this kind of having dependencies between classes hard coded inside an asp.net controller is not considered good programming style we do something different and this is an important pattern that you definitely need to remember we will practice it today we will practice it over and over in the next few weeks and i want you to really understand it how does that pattern work you go to your events repository and you create an interface for your events repository so what i do is i generate here a new class which i call i events reposit repository i events repository like interface then i'm going to do the following let's put that side by side i'm changing that to an interface see that one and then i add all the methods that my repository is capable of doing to my interface so i add the event the add method first one i add the get all method not the implementation just the signature of the method i add the get by id method and i add the delete method see it here that doesn't have very much value yet but i can now take the i event repository and make my events repository implement this interface you see now we say we have a contract this is called a contract okay a german for track a contract between our web api controller and the repository the events repository promises to fulfill this contract the events repository says all these methods dear web api controller you can rely on the fact that i implement those methods the events controller the api now will no longer directly access you can show it to you the events repository we will switch that to an i events repository so we essentially say i as the controller can work with anybody who fulfills that contract whoever implements this interface i am fine with if this is an in-memory repository it's okay if this is a entity framework backed repository i am fine with that if this is a mock object just just simulating the existing of a database during unit testing i am fine with that too now this is of course wrong because i want to get rid of the events repository can i just create an ievents repository no that's not possible because you cannot create an interface that's not possible because we don't know with whom we want to work with the database repository or with the in-memory repository that is no longer possible the question is where can we get the concrete repository from who is the authority saying if somebody wants to have an eye events repository this is the implementation that we are going to use the answer to that is dependency injection you've heard about dependency injection in other courses remember dependence injection in in um in angular for instance and i think we have also talked about dependency injection but today we are going to dive much much deeper in it and take a view on dependency injection from the co from the standpoint of asp.net core we go into the startup method here startup let's put it side by side here and in the startup method what we can do is here we can register the dependency injection configuration you have heard about startup before can remember what did we do in startup so far register the data context for entity framework but now we are going to configure services here and configure our events controller so what we are going to do is we will say services dot add singleton singleton means there is only one repository so that all the events are stored in a single instance of a class we'll talk about that uh maybe in the next lesson for today add single is fine and then we say if somebody asks for an i events repository return an events repository so we are linking the contract i events repository with a concrete implementation the controller on the other hand can now say hey asp.net give me an i events repository so it can't just wish to it can just ask asp.net to give him an implementation that fulfills the contract and now we have just to remember this guy this dot repository equals repository and this is now linked by asp.net by adding this line we will whenever we ask for an i repository z appears the i repository whenever we ask for an i repository asp.net core will give us an events repository the in-memory implementation of our image repository and when we want to switch that to an entity framework repository we need to make a change on a single line of code exactly here we can change it here from in-memory events repository to entity framework events repository and boom everybody who asks for an i events repository will create and get a different class okay that was a lot of information do you understand what i mean do you have any questions regarding that fine good having the repository implementing the asp.net stuff will really not be difficult the first thing let's add a repository sorry a controller operation which returns all the events let's do that http get because we are reading events public up until now we would have always written here i innumerable of event that would that is the pattern that we have used so far but now we are switching away from that pattern we are now returning an i action result there are other options too but currently we are going for i action result get all and the implementation is return what kind of status code do we want to return in case of get old events 200 okay correct so we write ok that will return see it here at 200 status code and inside of the ok we specify the result that we want to return in our case repository dot get all that's it so the business logic for accessing the database in our case it's just an in-memory list is separated from our events controller the events controller knows which status to return and that's it that is the most simple and robust no it's not perfectly robust but it is a simple and and good implementation for this api method we can make that simple by using the expression syntax it's up to you if you prefer the curly braces write the curly braces if you like the thing that i've written here then it's fine okay i'll give you a second to catch up now asp.net core has a little bit of a problem because it just sees i actually result by looking at this method here this one it doesn't know what it really returns it doesn't know that the return that the result will be a collection of events because from the method signature it just sees okay this returns an action result for that it is possible to add an additional attribute here on top we can say produces response type here we can say in this case we are returning and status codes dot 200 ok and we return the type type of i innumerable off edit with that we can tell asp.net core that the implementation will return a status code 200 and if there is a status code 200 it will return a collection of events this one is important because if we take a look at the specification here we have 200 and we are returning a collection of edens get the idea i hope you do okay that was for warming up let's do the next one let's do adding an event what is the correct http method for adding data it's post http post public i action result add and then we get an event new event where do we get it from from body we are getting the event data in json format from the http body okay got it nice how can we add this event to the repository we just say repository dot add new event we are okay what do we return okay new event is that one correct did i use the correct status code no which one should i use exactly and luckily there is a ready-made method for that created but this method created has a problem because it needs you see that one it demands a uri where the created uh where the created element can later be retrieved again so we ca we have to specify here some kind of uri where the created event can be found later on oh i forgot the return statement i'm sorry see that one so this is something this is a to do let's open it up let's keep it open for later on we will have to change something here and i will show you what we will add here later on okay looks good what if the user specified something invalid for instance if the user specified a negative event id if new event dot id is lower than 1 or zero or whatever you want it's just wrong what do we do then return bad request and we can here add some additional data okay we can at the very simple way and we will keep that simple for the moment in the next few weeks we'll talk about error handling a little bit more but now we say invalid id so with that we return a bad request status code 400 in case of the wrong id and we will return a created 201 in case of a created option now we have to generate the produces response type okay produces response type 201 created and what will be the response in case of a 201 a single event and we will also generate status 400 and the response will just be a string in our case here would just be a string we can also leave out the type if we don't want to specify the type we just say this method might return a 400 code but it also might return a 201 understand it i hope so next one delete http delete public i action result delete and here we will get an id because we have specified that in the url the id of the event should be part of the request path so we say int event id now event to delete id let's put it that way the problem is where do we get this event id from and the answer is we will add a route statement here another route statement which is relative to the route up here and we will here just say let's get a parameter and this parameter is called event to delete so this year this route will make sure that this method can be called with http wac wack api dot my server dot com slash api slash events slash 74 70 11 47 11 that will be the id and that will be the id here and it will be an integer good nice so let's delete the id var um no try because remember in the event repository the delete method throws an exception if the id that leads to a non-existent event so repository dot delete event to id to delete let's catch the argument exception okay okay let's get back to our example we catch the argument exception if we have an argument exception we know that the event does not exist so we return what not found see that one we do not use the exception here so we can get rid of it we just say catch an argument exception if there is no exception we return what okay because we want to return let's see 204 exactly so that is an example for a delete method now we have get all we have add we have delete the last thing that is missing now is the get buy id i will edit here after the get all method oh i forgot something sorry quickly go back to the delete method i did not add the producer's response type here of course of course we have to specify that the delete method in our case can produce what can it produce it can produce a not found or it can produce no content no con here it is no calling so don't forget that one in the next exam or in your homework i would like to see proper produce response type attributes on top of every api it's just a matter of good documentation now we will go back to our get buy id so we make another get http get that's correct public i action result we know that already get by id and the good thing is that we now can that we can now copy a little bit from our delete method because this delete method here already got an id here we just say id because it's not to delete and we already know that we have to use the route statement here and just change the name of the parameter let's take a look at the implementation get by id will either return the event or return null if the event does not exist this is how we have implemented so let's say var event equals to repository dot get repository event um existing event get by id if existing event equals null we will return not found otherwise we return okay with the existing event get the idea not difficult is it let's add the produce response type we already created a not found so i will just copy it here put it here and maybe i will copy that one up here status code 200 but we return it now that looks good now we have get all get by id add delete this is what i wanted to show you how to implement i will give you a second to catch up if you have any questions just interrupt me okay if you're done run it and do you see what we get we had a swagger file this is the swagger file that asp.net core automatically generates from your c sharp code and your proper attributes so it interprets all the stuff that you have implemented and it will give you the swagger file auto generated you did not have to enter all this thing and all these things in the swagger editor so asp.net core with its swagger integration is capable of generating this documentation out of the box we can even take a look at the technical swagger file this is the technical swagger file in json format and it looks pretty much the same as what we have entered you see that here as what we have entered in our swagger editor so this is super super useful if we take a look at get events we even get see that one nice documentation of our c-sharp classes here we see the response codes for instance we see the post event the get event by id you see that one with the required and all this stuff so this is really really super useful and you might ask yourself why did mr stropak show us how to write that by hand now that we can just generate it from our c sharp code well you are right to a certain extent this is generated from your c sharp code but in real life you cannot just invent your api you have to think about it first so the typical workflow in a real life api project is you write a documentation a specification like that this will be your specification this forces you to plan can you remember what i told you at the end of the last lesson you need to plan a little bit this will be your concept you walk out of the door and you make a at least rough plan how to get to vienna this was the picture that i used then you really implement the code and the nice thing is that if it turns out that during implementation you find out that your plan wasn't perfect you have to make slight adjustments to your plan and the beautiful thing here is that you do not have to enter the slight adjustments manually here but once you have implemented your api you can't forget about this thing this will be in the past this was your plan and this is reality this is what you really implemented and that's the whole idea use swagger to specify then implement and from your implementation generate the documentation which is really 100 in sync with your implementation you do not have to manually maintain your plan you can just generate it that's the workflow another nice thing is that we can if we want directly try out the api here you see try it out click on try it out click on execute and the result will be as you can see here an empty array and this really executes your api let's try to add an event see that one try it out here let's specify id date i don't care about can be something it will be somewhere and the description will be a great party if i hit execute we will get a response code 201 exactly as we expected and if i scroll up again go to the get events and execute it again we now get our great party so once we have our swagger documentation it's really very useful to also try out the api of course it's not absolutely necessary you can also here type it in in the browser 5001 get events and get uh oh https uh i forgot api i'm sorry i'm sorry api come on ah i misspelled it good now we are done sorry for my messing up here okay now that looks pretty good and that is exactly what i wanted to show you today and we have now finished the third lesson it's 11 o'clock and that is that was exactly my plan to use three hours to recap http to talk about swagger and then to implement an api in very much more details compared to what we did before so what do you have to remember in asp.net core from this lesson you have to remember that you should not you should never directly add business logic or data access lodging interacting with your database context directly in the implementation of the asp.net core controller you shouldn't do that what you should do is you should extract your business logic your data access logic into separate classes where you offer some helper methods some services to the rest of your application first one next one use an interface to build a contract between your asp.net core implementation and your business logic or data access logic then third thing go to the startup class and register your classes with the services i told you that there are multiple options here it's not just ad singleton there is more to talk about but hey we only have three hours today it's fine for today and for this for this homework that you have to do just to remember at single that's fine here we are connecting the interface with the implementation in asp.net core we are then using constructor injection to get an implementation based on the interface but there is no tight connection between the implementation events repository and the controller events controller the interface is in between this is the abstract contract between the controller and the implementation in the controller you use the http methods we talked about them at the beginning of this lesson get post delete we could also add a put or a patch but that will be part of your homework we add if necessary some routes we add some attributes to document which kind of response codes we are going to create we are adding some logic where we mainly call the underlying business logic or data access class and just translate the responses into proper http responses like not found okay created and so on and here we have the no content now we still have this to do down here and i told you that we need to change something here in order to reference another action it has to do something with the location header and you will see that in the result in a second so how do we do that correctly first we need to change the definition of our get by id a little bit we have to move this parameter here into our http get so i remove that one and now the route is directly in the http get and then what i can do i can give this route a technical name so i can say this name is name of get by id so the technical name of our route should be identical to the name of the method in c sharp with that we now have a technical name with which we can reference this route from this this created here so what i can now do i can say created at action and give it the name of the route the action it's also called so name of get by id and tell it that the id parameter up here in this case is oops is the new id new event dot id that will now link the result of the add method to the get buy id and the id parameter here and what is the result of doing that let's try that application coming up here is our swagger document if i now create a new event data doesn't matter click on execute and this is the result this is what what i was fighting for the location header i now automatically get the location header with which a user can retrieve the data she just added with this body okay so let's go back if we want to get rid of this to do move then the the route parameter into the http get and use the created at action to link the result of one action to another action or the create sorry to link the location header of the created response to another action which can be used to retrieve the data that we just created okay now what is your task for the rest of this morning's lesson your task for the rest of this morning's lesson is to work on the homework on the classroom that i gave you so let's quickly um take a look again at the exercise your classroom is that one you have to implement a contact list and for that you have to take a close look at this swagger file we already worked it through so you already know what to do but you have to take this swagger file as a specification it's fine to implement an in memory implementation so just as we did now use a list that's fine you do not need to use entity framework if you want you can but it is not necessary here i also told you to use n swag but you can use swashbuckle to just you can make it exactly like we did in the lesson here and i want to have at the end of the day an asp.net core implementation which does exactly what this swagger files demands okay so you have to implement the get post and so on if you want to make your life easy you could just copy the code that we created in this lesson make a few changes and you're done i would not recommend that you can do that it will be a fast track to a solution but you will not learn a lot my recommendation is that you open the code that we have written throughout this lesson on one hand and then create a new solution and try to build everything on your own and whenever you struggle because you don't remember what how to solve a certain problem then you take a look at the code that we wrote together during this lesson now that would be the most uh most elegant way of learning and and trying to remember all the things that we covered in this lesson can you earn an extra point yes you can if you fulfill all the requirements and you are done check in the solution through github classroom and send me a github issue and then i will take a look at your solution and if i think it is good you will get an extra point a thumbs up then you know it everybody has to check in the best try so it is mandatory you have to check in something i will take a look at random homeworks and make sure that you didn't just check in i don't know a git ignore file or something like this i will not take a look at every homework if i don't get a github issue but you have a certain risk of me taking a look at it so please try your best okay nice with this we are done with the theory part do you have any questions now that we must discuss before you go into your exercise
Info
Channel: Rainer Stropek
Views: 2,913
Rating: undefined out of 5
Keywords: C#, CSharp, ASP.NET, ASP.NET Core, Web API, Swagger, OpenAPI Specification, OAS, HTL Leonding, REST, Programming
Id: ksy8LK5M1Ts
Channel Id: undefined
Length: 56min 57sec (3417 seconds)
Published: Thu Jan 21 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.