GraphQL API with .NET 5 and Hot Chocolate

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
so 2020 was without exception a wonderful year for everybody all around the world myself included and in 2020 i talked a lot about rest apis so much so i even wrote a book about rest apis but in 2021 i'm shifting my gaze and i'm looking to the future and i'm looking towards graphql [Music] well hello wherever you are whenever you are the year is 2021. my name is les jackson and the place at least for me is melbourne australia now i hope wherever you are and wherever you are that you're happy safe and well so it's really fantastic to be back here on youtube this is my first video for many months it's my definitely my first video of 2021 and i'm really excited to be back and what a video i have for you because today as i said in the introduction we're going to be building a graphql api using.net 5 and the hot chocolate framework now i can really say hand on heart in all honesty i love rest apis awesome but having used graphql now both as a consumer and as somebody writing them for about six months wow i can really say i've fallen in love with them and i think they are fantastic and i don't think it's just another faddy technology i really think they are here to stay now there are some definite challenges with building graphql apis that are harder to build than rest apis no doubt about it but i feel the payoff for your consumers is awesome it's really there and again i bought some misconceptions about graphql before i used it so i hope this video not only teaches you about what graphql is and why you would use it but hopefully it will bust those misconceptions if you were like me and you have those misconceptions fantastic so just before we move on to the demo i'm going to take you through what you're going to be building if you follow along with this video just like to say if you're not subscribed already please think about subscribing and you'll be notified of any new videos that i make and if you like the video maybe give it a like again that just helps me out and i really really appreciate it other than that we have got a lot to get through thanks for joining me but let's get started all right so we're going to begin with a bit of a demo on what we're going to build but before we do the demo i think it's worth just talking about the api we're going to build and i've tried to make this as real world and as useful as possible okay and it's the same use case i used in my rest video where i talk about the use of command lines and being retrieving command line snippets that are difficult to remember but unlike the rest tutorial where we just had one resource which was our commands resource and it actually had a string for our platform in this example and this is really me trying to kind of sell the benefits of graphql i've split out the platform which is really going to become our parents object or parent entity which just is something like net or docker that's what i mean by a platform and each one of those platforms can potentially have one or more command line snippets so it's a much more elegant way of representing those resources now it's not to say you cannot represent resources like that and rest you absolutely can and we'll touch on um some of the issues with that a bit later so i'm going to cover that here so i'm not saying you can't do this with rest you can but it's i feel a bit easier and a bit more intuitive doing it with graphql so this is what we have we have a commands table with our command line snippets and a bit about what they do and then our foreign key that relates to the platform so let's just have a quick look at some of the data just to help you contextualize it so if you do a select other thing from uh platforms you'll see i've got a few platforms in here so net5 docker ubuntu etc and we have a license key column don't worry what that means at the moment that will become clear a bit later and then if we have a look at our commands yep you'll see all the different commands and you know of course they have a foreign key that relates to the id of the platform and we can then start working with it in that way so they don't worry too much about the data it's just kind of rubbishy simple data but that is what our api is attempting to do so let's start querying that api using graphql and again i'm not going to over explain it at this point we do go through it step by step later so let's just do a net run to run that up and that's going to run on localhost port 5000 as you would probably usually expect a.net app and then what we're going to use to exercise our api is a tool called insomnia now if you wanted to use postman you absolutely can use postman and there's actually another tool that comes built in with the hot chocolate framework that you can use as well so we cover all this later i'm going to use insomnia and it's just an api request client and you can actually use it to test rest apis as well so let's do a query let's pull back all our platforms let's do that first so i've got a folder for my queries so right click new request and we'll go and say all platforms okay now all requests in graphql are all post requests so it's not like with rest where you would have a get request for reading stuff and a post request for writing stuff not like that with craftwell everything's a post request and we'll select graphql as a body and all that is a graphql query that we're going to put into the body of the http request so this is just a http request no different no more complex than that all right now we're getting a bit of an error here so what we need to do is put in the end point and this is another difference between graphql and rest there is only ever one endpoint with graphql you don't have to change the the resource uri depending on what you're pulling back so just localhost port 5000 it's not semicolon so cool on and then the actual endpoint is going to be called graphql and we'll cover all this a bit later so let's refresh something called the schema and this is a really important spell http rom this is a really important concept in graphql the idea of a schema and again we'll cover that later but basically it's what we can do with our api is loaded into this tool now and it knows the things that we can do with it so we're going to write a query and this is just the stuff that goes in the http post body request and you can see here straight away it's aware of the objects that we have within our system so we want to pull back a platform object and we want to bring back his id and we want to bring back its name okay so this tool is quite cool it gives you kind of intellisense functionality you just click send you can see here it brings back jason so again another important point it just brings back jason i mean it can bring back anything could bring back xml if you wanted but again it's just a json object that's coming back with all our platforms in it but what you may have seen that's the really cool thing about graphql if you set it up correctly we can then access the child objects in this case our commands and we then just drill in to the stuff that we want to pull out from our commands for example for example how to and of course the command line snippet as well let's rerun that you can see here we get back and more of our bose output with all our platforms and you can see we have command line snippets for net we have some for docker we don't have any for windows we have one for ubuntu and we have one for kubernetes and red hat so you can flip this about and you can just request the commands so ends down your request and let's do all commands again always a post request graphql for the body create and i'm just going to put that down here and i'm going to copy our end point again labeling the point it's the same endpoint for all our requests paste that in here refresh the schema specify that it's a query what query is it this time we want to just go straight to our command query and we want to pull out all our how-to command line and we can then drill in to see what the platform is and we just want to pull back the platform name fantastic send that over and we get just the command line snippets with the child object that's not the child object with its parent object which is platform so you can see the power of this and you can see the fact that you could platform had a parent object or if command line had more children objects you could drill down as you wanted you can select what attributes you want to pull back so let's say we don't want to pull back the how-to attribute to minimize our payload you can take that out send it over and that's gone and all you're getting is the command line and the platform so very powerful i think much more powerful than rest the last thing we want to do is show you how to create data so we can create and add a platform to our backend so right click new request so we'll do add platform again as a post request graphql for the body create we will copy our endpoint so again the endpoint remains exactly the same fantastic schema refresh this time we specify that it's a mutation and that's what we call in graphql world and we'll cover this a bit later when we talk about the theory anything that changes data and we've got a couple of mutations here add platform so we'll specify a platform input and then we just specify the parameters in this case we want to supply a name and then we'll just give it a name so let's say i don't know os x or something doesn't really matter and then you can see here it's kind of complaining what it wants us to do yes that's us telling what we want to create the data with but we then want to specify uh what we want to display as a as a return and the ad platform mutation returns a platform object and then we've got access to all the stuff that we want so i'm just going to select back id click send and you can see back we get id 13. if you look in our database and select everything from platforms you'll see that that has in fact been created in the back end so that's a very quick demo um we're going to look at these in a bit more detail we're not going to cover subscriptions here which are really really cool actually but you will build subscriptions and graphql so that's the demo done now we're going to move into the course overview so you can see how we're going to get to this end point okay so we're just going to take you to the course overview now and yeah just in case you didn't realize we are doing a craftql api using.net 5 and we're using the hot chocolate framework in this case and yes this is the first episode of season 4 as well for those of you who are counting so this is what we're going to cover in our introduction section which is really where we are now i'm going to show you the demo which we've done already tick uh we're going through the course overview so we're in that right now then going to take you through the application architecture of what you're going to build and then we'll talk about ingredients and tooling next section is a bit about graphql theory and i recommend you watch this section it's not that long but if you've not used graphql before then i highly recommend you you stay and watch this but now just on that point if you do know about graphql you know what it is and all the terms and stuff then i will put the time codes to these various sections in the video below so you can just jump straight to the relevant place and also means if you're following along and you decide to take a break you can jump straight back in to where you left off so time codes will be below the other thing as well the all the code is up on github and i'll flash down uh in the video where you can get that code and i'll also put it in the description below so the code is there if you want to download it from github rather than typing it in but i personally like typing it in as i move along i feel like learn more about it anyway just a couple of points before we move on so yes the graphql theory we'll talk about what it is why you would use over rest some core concepts some core language concepts and then we'll talk a bit about graphql in the.net world we'll move into coding then and again code is on github just remember but we'll do a project setup right from scratch step by step we'll set up our models in our db context to set up our kind of data layer we'll then do some simple querying but then we will need to revisit db context and i'm not going to ruin the surprise as to why we need to do that but we will do that in the second part of our coding we're going to talk about multi models we're going to introduce a second model we're going to talk about something called annotation versus code first approaches to writing a graphql api with hot chocolate um now so i don't expect you to understand what those mean right now um we're then going to introduce you to types why you would use them and then we'll talk about filtering and sorting support as well especially within the query context including part three we're going to talk about mutations which i kind of did a bit in the demo and also subscriptions which are basically real-time event notifications back to a client very very cool and we're going to implement that as well so move on to final thoughts i've got some ideas for some next steps where you can take this this is a full api in my view um but there may be some things you can add to it as a next step so i've got some ideas on that do a bit of a wrap up and then support our credits so that's our course overview all right so in this section we're going to take a closer look at our application architecture now we cover this throughout the video and don't worry if some of the some or all of the concepts in here don't make sense to you we cover all step by step i just wanted to give you an introduction to it to see the kind of thing that you're going to build so we'll kind of start with our application boundary we have our program class which is the entry point for our program we then have our startup class that's responsible for configuring our services as well as our request pipeline and there we are a request pipeline i'm showing that on here now request piping deals with requests but it deals with them in a particular way a sequential way using middleware and some of that middleware we need to introduce as part of this request pipeline most specifically graphql we're adding it to our pipeline as well as websockets which is used as part of our subscriptions component of our api we'll have our models as usual but say as usual we'll have our models which we will have in probably most applications so this is nothing really to do with graphql specifically anything in blue is not really graphql specific we'll have our data access layer or db context which i just think of as a mediator between our models and our database so they take our internal data representations and mediate them down to a persistence layer we're going to start with the graphql specific stuff and the first thing we're going to create is a query class which will allow us to read data not surprisingly so we'll work with our graphql client to make a http post request go through a pipeline hit our query the query will use our db context to pull data back via http response which is in json and you've seen that already in the demo we're going to introduce this concept of types which are basically mapped i like to think of them as just being mapped to our models and it allows us to abstract away the graphqls any graphql specific stuff that we may have embedded in our models and extract out just into our types and that allows us to not expose our models in their entire attainments we can hide some fields for example that we don't want to expose out via our api so it's a really important concept but i'm going to introduce mutations which allow us to create update and delete data and they require two support classes namely inputs so not surprisingly when you're trying to mutate data create it destroy or update it you need to provide some kind of input make sense and then you would expect some kind of output or or in this case a payload as a return so we're going to introduce those as well and then finally we're going to introduce our subscription type which will allow real-time event notification from our api so we're building a full draftql api queries mutations subscriptions okay the full works and just to round off our architecture section this is referred to as our schema but i'm going to go into a bit more detail around this when we cover off our graphql theory but for now that's our application architecture section done if you didn't understand all or any of that don't worry we explain it as we go and we will be revisiting it throughout the rest of the video all right super quick section uh just telling you what ingredients you need to know again i'll put links to all of the things that you need to download and install and attach to this video and that is a subsequent section later on where we actually go through the environment set up so and i kind of take you through this in a bit more detail but i just want to give you a headline overview of what you're going to need so you'll need a text editor i recommend vs code it's free you'll need net5 and again you actually need dot net 5 it's not good enough to say you're going to use 3.1 or even an older version because we use some new features as part of.net 5. and again i'll take you through that a bit later in a subsequent section about where you can find it and how you can download it we're going to be using sql server so again i don't really mind how you have access to a sql server you can have it installed locally on your windows machine or you can have it in docker which i'm going to do and again i'm going to take you through in our environment setup section how to set up sql server using docker if you've not done that before but highline headline should i say is you need sql server i recommend sql server express or if you've installed visual studio you'll probably have the local db up to you which you want to use and again they're free and then you'll need a api client and i'm recommending insomnia for this video it's free or you can use postman if you're more familiar with that but for me insomnia is actually a nicer interface it's a bit cleaner and it has much much much better graphql support so strongly recommend insomnia but it's entirely up to you i'm actually going to use a couple of other tools that i'll introduce you to later in the video and then i've said about two hours of your time i think this video is probably going to be over three hours long so you know it's up to you how you want to ingest it you might want to come back as i'm sure you probably will do and revisit it if you want to work your way all the way through it so probably more than two hours of your time but i'll put that there for now so that's it that's our ingredients you'll need everything is free shouldn't cost you a penny and i do take you through how to kind of find and set up your environment in a bit more detail later on all right so we move on to a bit of theory now and i think it's worth going through this especially if you've not done any graphql stuff before so first off what is graphql so it's a basically a query a manipulation language for apis as you've seen in a very basic way as part of the demo but it's also the term we use to describe the runtime that actually fulfills requests so graphql is both the query language which you've seen when we did those queries and mutations but it's also the runtime so the hot chocolate framework basically implements a graphql runtime that we build around okay so it's both of those things it was created at facebook to address some core concepts of over and under fetching and i'll talk about those in detail a bit later and it's now open source so it's now hosted by the linux foundation all right so let's go through some cool concepts and again at the end of this if you don't understand all that's okay i think you'll probably get it more as we move through the coding examples but i wanted to in this section here at least introduce it to so you're kind of starting to get a bit of a head start on what some of the concepts are now i've tried to get the core concepts onto one slide which i thought was quite difficult but um you you'd be the judge and tell me how well i've done at doing that but the main concept if you walk away with nothing else from this slide the main concept i want you to remember is this idea of a schema and a schema basically in the graphql context describes our api in full so the queries that you can perform the objects it contains the data types that it has even down to descriptions or documentation for all of those things as well and we actually do that in this video too so yes self-documenting which is awesome it's comprised of types and we'll talk about types in a second and yes you must have a root query type so we talked about queries we talked about mutations talked about subscriptions as far as hot chocolate is concerned you must have a root query type so what are types well this is a bit confusing types can basically be anything in graphql so query is type mutation is also a type as is a subscription we have objects and i'm sure you're aware of what objects are but they can contain additional fields and they can contain additional objects as you've seen and they can use them to construct more complex business you know sort of modeling scenarios we then have enumerations which are basically lists of static values and we can also have scalar values and scalar values are just the the values that you're probably very familiar with using now they actually call out interestingly in graphql they call out an id as a scalar type so it's got its own special you know special reference integers strings blanes floats they're all scalar types and as i mentioned objects they allow you to make up more complex things so an example of a car we have a car object and this language that you see here is the schema definition language of graphql so you have a query language but you then also have like a schema definition language and that is what this is here so here we're defining an object of type car and they will have multiple fields in this case so make and make in this instance is a scalar type which is a string and the exclamation mark means it cannot be null so again yeah just to elaborate the point each of these fields will have a given type all right so we then move on to this concept of resolvers and all the resolver is is a way in which we understand how to get data for a given field so i think i've got a comment here yes so result resolver returns data for a given field now when we kick off our genre into graphql the resolving heavy lifting is pretty much done by the hot chocolate framework so you don't really need to worry too much about it but about halfway through the video we change course and we do a bit more of the heavy lifting ourselves and then we actually start to write our own resolvers and they can resolve to anything so your data sources can include other databases or databases as we're using another microservice a rest api and in fact another graphql api can resolve to absolutely anything so very flexible so these are the core concepts from a non net perspective so yes that's a really good point this is a graphql core concept so these concepts are as relevant if you're building a graphql api in ruby on rails or node or something it doesn't matter this is agnostic from the technology implementation these are just core graphql concepts that you can use no matter what framework you're using so that's another really important point and then finally interested in the section i want to talk about what's wrong with rest what is wrong with rest nothing and what i don't want you to think i'm doing in this video is jumping on a bandwagon and going rest is rubbish never use it because i don't believe that to be the case at all however rest is not perfect as i said there's nothing wrong with it but there are some things it doesn't do so well so let's take a look at those so the first idea is over fetching now what that means is we return more data than you need so rest does overfetch so let's look at an example called a rest resource called cars so we're going to bring back our list of cars and in a typical rest request you'd get all your cars back we've got three here and it's going to give you every attribute every property for your car now it may be for the query that you're making you're only interested in its id in the registration number and the color is irrelevant but you're still getting to be you're still given that as part of a rest request so you're getting more data than you need so scaling that out becomes quite inefficient with graphqls you've seen you'd specify a query and you specify yes we want the cars object but i only want to select the fields that i want in this case id and registration so this is passed in the body of a http post request as you saw in the demo and you will just get back the data that you want so it avoids this over-fetching scenario and yeah we get it back as a json payload so again one thing i just want to make clear is for both rest and graphql we talk about http posts and what have you both rest and graphql do not need to be implemented using http they most usually are but they don't have to be they're agnostic from that implementation and likewise the payload most usually happens to be json doesn't have to be json though so just just bear that in mind as well so problem one solved by graphql you are getting only the data that you need so we'll then come on to talking about under fetching so rest also under fetches so meaning that you need to make more requests using rest than you would with graphql so you're not getting enough data back so let's take a look at an example so we're extending what we did in the last slide and we're just asking for one resource this time so we're using the resource id of one to bring back one car and you can see not only does it bring back every uh field for the car it's also bringing back our options now what are options options in this imaginary scenario is a child object of car that allows us to model things like you know does the car have you know metallic paint and alloy wheels and leather interior all that kind of stuff now if you're implementing rest correctly you wouldn't put all that information in the response because well you're basically just compounding the original issue that we had of over-fetching so imagine you only wanted a car's id and a car's registration and instead you're getting all the car attributes and every option attribute as well it's not really what you want so that's not actually solving the issue even if you could do that you shouldn't do it so what you'll usually get with rest is yes you'll get your options array and it's just a link to the resources in question and so to get the options information you're going to have to make three additional requests so it's just this horrible self self kind of you know referential cycle of over and under fetching and it's not that great actually and that's why facebook obviously went well there must be a better way of doing this so again graphql comes to the rescue so again just to mirror um what we're doing over in rest we're specifying we just want a car with an id of one we're only specifying the id and registration attributes for our car so we're not over fetching redundant information but we are addressing the under fetching issue by saying we actually want the options included in our payload but we only want the name and the cost or whatever it doesn't really matter now an options object could be massive as well so again you know you wouldn't want to again laboring the point you wouldn't want to pull it back here with this request anyway even if you could and so what that will result in is adjacent response payload with you know just the id of the car and the registration and then our options array just with the information that we want so we've made one request to one end point not four requests to four endpoints okay so that is the beauty of draftql and i definitely don't think that's a fad i think that's an absolutely fantastic selling point for any api so when to use it so i'm not totally bagging rest you know um again i'm trying not to jump in a bandwagon but i am very impressed with graphql so graphql is good for interactive quote-unquote real-time tech applications mobile applications applications are quite chatty where you're you know wanting to pull back really complex uh yeah they go complex object hierarchies just once good for that good for complex type queries rest apis are good for maybe system to system interactions such as microservice where you've got more simple object highlight hierarchy potentially where you're having repeated simpler queries the other thing to really bear in mind and you'll see this as we move through the video is graphql apis are much much harder to create than rest apis rest apis are very simple but as a consequence from a consuming perspective they're not optimal so the trade-off is as a developer rest apis are easier to write from a consumer they're probably not as good as they could be graphql apis from a developer perspective are much harder to write but from a consuming perspective for me they are much much better but ultimately as a developer you should have a toolbox okay you should have a kit bag or whatever you want to call it of techniques and design patterns that you can use so i'm not saying for one minute drop all your rest stuff and use graphql api across absolutely everything definitely not seeing that and i'm not saying the converse either what i'm saying is as a developer you should have a kit bag and you should understand when to use the right approach i'm going to use it right approach is not a good technology when to use a suitable approach all right so the final slide in this section and i'm going to get off my pedestal or my preaching stand and just talk a little bit about graphqlin.net specifically so if you go to the new get package manager website you will find that that is by far and away the most popular library for graphql in the dotnet world it's open source there's over four million downloads i'm not using that in this in this video i'm going to use the hot chocolate framework which is by a group of people called chili cream i think again open source and it's just under a million downloads um as of this video now we are using this one and you might go why are we using this one why aren't we using the more popular one well the hot chocolate framework is far newer okay it's not been around as long and based on my own this is you know flash up my warning this is my personal preference i'm not advocating uh one is better than the other but for me personally based on what i have seen and what i have used i personally prefer hot chocolate it just seems to work quite easily it seems very robust i get it i get how they've structured things it makes sense when i looked at graphql.net i have to say didn't quite didn't resonate with me it might resonate with you and that's cool i'm not bagging it but for me hot chocolate was definitely the way to go it wasn't even really a choice it was i'm definitely going down this path after what i've seen and experienced seems to be really well supported um yeah so that's what we're using and i think it's going to have many many many more downloads than that in the near future so i may be wrong but uh we'll find out i'm sure in the future anyway that is our theory over and i think now we're ready to move on to coding up our solution all right so in this section i'm just going to take you through how to check to see that you've got all the necessary prerequisites installed if you're wanting to follow along so we went through with those we went through what those prerequisites are in the in one of the previous sections but here we're just going to check to see if you have them so the first thing you want to check to see that you've got is dotnet so at command prompt type.net version and that should return a version number and we actually need version five as some of the features the new features introduced with version five we are actually going to leverage and use in this course now if you get a lower version number returned like 3.1 or something like that or you don't get anything any version number returned and it just doesn't know what you're talking about you will need to install version 5 of the framework so over in the browser you just come over to google and you just search for net and i'm still using i still use dot net core it tends to take me to the right place that i want to get to which is this page here so dotnet.microsoft.com forward slash download and you can see here it's detected and running on windows so it presents me with the options that i have available and this is what i would want to install and download or download and install if i didn't have dot net 5 same for linux you'll want dot net 5 sdk same for mac exactly the same thing now i'm not going to take you through how to install it is very straightforward just follow the instructions on this website so that's the first thing you'll need to check the second thing you'll need is a database and we're using sql server in this video now there's two ways broadly that you can run sql server if you are running on a windows machine like i am you can install it directly on your machine and now i've actually done that i have it running sql server express running in the background so if you want to do that just type sql server express into your browser search engine and go to this downloads page again i'll put all the links attached i'll attach all the links to this particular section and this is the this is the download you want sql server express so if you want to do that do that follow the instructions pretty straightforward and that's you done as far as the database is concerned if you're running on a mac or you're running linux or you're running on windows and you don't want to install sql server then you can use docker to run sql server in a container that's an option as well so if you want to take that approach again over to google and then just type in docker download and you will get various options depending on your operating system so if you're running windows or mac you can download something called docker desktop if you're running linux you just use docker now if you are running windows and specifically if you're running windows 10 home edition you need to take a slightly different approach to installing docker but there is an article here on how to do that so again i'll put links attached to this video and you can you can install it that way if you're running windows 10 home now you can just remember install sql server directly on your machine if you find that easier it doesn't matter which approach you take you just need the database i'll leave it to you which approach you want to follow now if you are wanting to use docker i will take you through in one of the following sections how to actually set up sql server in docker and run that i'll show you that bit later but for now just want to make sure you've got prerequisites installed cool so that's net sql server you'll also want a development environment so i'm recommending visual studio code so again yes code download and the reason i'm recommending that is because it's a nice cross browser cross cross browser cross-platform development environment same for linux windows and mac looks the same works the same so from my perspective making videos it's a nice option it's also a really nice tool as well so yeah i highly recommend it if you want to use visual studio the full-blown ide you can do that you should be able to follow along with relatively few changes required and if there's anything i can think of specifically that i need to call out that you'll need to do differently i will of course do that but generally speaking you should be okay if you don't want to use either of those you can use any text editor that you like and just use a command line along with it that's all good so the final thing that you'll need is some kind of api client i don't know why i minimized my browser though let's bring it back up now in previous videos i've used what i've been doing rest apis i've used postman which is a really good option for rest apis but for graphql i'm using a different tool and i'm using something called insomnia now again i wouldn't recommend you just search for insomnia because you'll more than likely get a lot of results about sleep problems deprivation so i wouldn't suggest that so type in insomnia api and it will just take you to the downloads page and interestingly it's got it's called insomnia it's named insomnia.rest is the url we're using graphql in this video obviously not rest now what you'll need to install is this insomniacore product and it is available on windows mac and linux and the reason i'm choosing to use it is it's just better graphql support built in and i'll highlight some of those um features when we come on to using it so that's it that's the prerequisites that you'll need i will put all the links i'll attach them to this to this lecture so you can go straight there and download them otherwise just google google them insole is very straightforward for pretty much all of these across all platforms so i think you should be okay in following the instructions provided and installing them so that's it for this section and we're ready now to move on to project project setup all right so in this section we're just going to scaffold up or set up our application we're not going to do much coding we're just kind of going to get it going so i'm going to open visual studio code by just launching it from my taskbar i'll bring that over onto my main screen now i'm going to open up the integrated command line from within visual studio code which is one of the reasons i like it so i'm just going to hold down the control and open quarterback back quote apostrophe it's the key well underneath your escape key and above your tab key if you're using a us type keyboard i think it's called an acute as well so it's a kind of back single back quote key to open up now at the command prompt i'm just going to change into my kind of working directory which in my case is on my d drive and then it's in season zero four or maybe it's just s4 yes season four s4 cool and then if i do a quick directory listing there's a folder here for episode one so i'm going to change into internet as well cool so let's do a quick clear the screen now you're probably aware of this but if you do net new you will get a list of templates that we can select from to scaffold up our application so the one we want is this one here the asp.net core empty project type so this web kind of key here is effectively the short name and you use the short name to you know but you'll see how we use it in in a second so clear the screen dot net new and then just the short name to select that project type and then we'll give it a name and i'm going to call this commando little and might see graphql from time to time abbreviated as gql so command or gql hit enter and that will then scaffold up that uh that project so we'll do a quick directory listing you can you can see it here so i'm going to change into that folder actually no i'm not what i'm going to do i'm going to do a little bit of a trick i'm going to open code up vs code up recursively which means it's going to open it within itself and i'm going to give the name of the project gql there you go and it's kind of reopened visual studio code with that folder and you can actually see that the project structure here which is quite a nice little feature so yep we're going to rebuild our assets there you go now again i'm not going to spend too much time going through the anatomy of of what you've got here because we'll kind of cover it as we move through the tutorial but just very quickly we've got a project file we're going to keep this open in this section and we're going to add some packages and references package references to this file for all the dependencies that we need our program class is actually our entry point to the application we're not going to touch that but this is basically where everything gets kicked off and then within here which if we take a step back into our program class basically what it ends up doing is calling our startup class and within our startup class we're going to configure two main things our services which is done through configure services no surprising surprises there and also our request pipeline which is done in our configure method but more on that later those are the main things that we're going to need and then actually the other two things that will well one thing really that we'll be interested in is either one of these json files which is going to hold our connection string or any other config that we choose to put in and we can choose either one of these i'm probably going to put stuff in app settings development json as we're working within a development environment but you can use either one of these really depending on your needs and that's probably about it that's all that's really relevant i think for this project if i've forgotten anything i will cover it as we move through the rest of the video so open the command line again so again control and back quote or single quote and i'm going to leave actually that's not the right file we want i'm going to open up this project file the cs proj file and keep that open and we're going to just start adding the packages that we need as part of this project we'll install them using our command line and they will automatically get added to our cs proj file now visual studio users yeah visual studio users you will have to do this a slightly different way and you can do it via the gui or you can do it via the package manager console but actually let me show you how you can do that so all packages come from something called the nougat package manager so if we go over to google let me just type in nougat package now take us there i'm sure so here we go and this is basically the package repository if we're going to pull everything from and it gives you some well it actually gives you how you can do it how you can install these packages depending on what environment you're using so the first package that we are going to actually work with is the main graphql package which is hot chocolates choc hot choc hot chocolate that's right and actually if we just type that that should take us there so it's hot chocolate asp.net core we want this one here and you can see here for if you're using visual studio you can install via the package manager we're going to be installing it via the.net cli or you can just copy in the package reference however you want to do it we're going to do it using the.net cli i'm just going to copy this and then come back over to our command line and paste it in now i'm just going to take out this version attribute here i just want to install i don't want the preview version i just want the latest stable release so net add package and then let me move my cursor out of the way the name of the package and the reason we're keeping this window open here is you you should see it added up here if it's successfully been added so you can see quite a few uh quite a few dependencies are being added in here so hopefully there we go after all that we get this one package reference line and the latest stable version is 11.0.8. next thing we want is another hot chocolate package but this time it's hot chocolate data dot entity framework okay that should be correct and we'll just do an up key and again the reason i like to keep this cs proj file open is if you've made any typing mistakes you won't see the entry being added in here and a few times i have typed something in at the command line i've not really been paying attention it's thrown an error and i've not we've not actually added the package or i've not actually added the package to the project and i've ended up chasing my tail a bit so that's why i like to do it this way it just kind of validates what you're doing is is working and you've done the right thing so the next one we want actually is an entity framework core package so they're not up key it's not a hot chocolate package this time it's a microsoft package so mike microsoft entity framework core dot design [Applause] and you can see there's definitely room to make typing mistakes in fact i probably should just be copying these over there you go but it's installed correctly and it looks all good and then the next one we want is another microsoft entity framework core package but this time sql server and this is the obviously the package you install if you're using sql server if you're using a different database you would find the appropriate package for that particular database but we're using sql server great and then there's one last package that we are going to be using in this tutorial so i'll cover a bit more in a bit more detail later but it's basically it adds a really nice graphical interface to our request pipeline and it basically allows us to interrogate our graphql schema now if none of that made sense to you don't worry i'll cover off in full as we move through the video but we do need this package so the package you want is graphql.server.ui.voyager and the tool is called graphql voyager it's really nice yeah you'll see how that will manifest in later sections but let's just add it in there for now so we don't have to do it uh later so that's really it for our project scaffold and project setup as i say we're just adding some packages to make sure we have all the dependencies that we need so in the next section and this is an optional section is we're going to set up our sql server in docker if you're choosing to do that if you have sql server already set up and running you can skip the next section you don't need to follow along of course if you're interested in how to do it take a look but that's what we're going to be doing next okay so in this section we're going to set up sql server using docker and in fact docker compose if you want to be absolutely correct now you can skip this section as i've just said if you already have sql server running if you don't and you want to use this approach then i'm going to take you through that now so of course you need to have docker installed then in fact let me just start my docker desktop instance while uh while i'm doing the rest of the the config stuff and you can see down here certainly on windows you get a little there you go docker desktop is starting so let's let that let's leave that happening in the background while we go on with the docker file so in your project in the root of the project just click anywhere here a new file and we're going to call it docker dash compose [Applause] okay so obviously it's a yaml file now yaml if you've not used it before is very very sensitive to indentations and white spacing and stuff like that so be really careful with how you type in your docker compose file now what a docker compose file is is essentially a set of instructions that we feed into docker and it basically tells how we want it to spin up one two three four however many containers that we want now in this instance we're just spinning up one container which is going to run sql server within docker compose we actually refer to those running containers as services so the docker compose file is really concerned with setting up our services so that's what we're going to do now so the start every docker compose file is specifying a version and i'm just going to specify version 3 and then we go on and start specifying our services so again colon and then we want to indent so again i've just indented under here so i'm using two space tab tabulation if you want to use something else that's of course fine but make sure you keep it consistent and if you're going to get any errors it's going to be in and around either typos or you've not indented properly so the first thing you do is just specify your service name and this can be anything so i'm just going to call it sql server which i think is a good enable as any and then for the rest of the service specification i'm going to actually copy that in and i'm sure you uh hold that against me just because it's so subject to making typo errors and it's there's no intellisense or anything well not much intellisense so um i'm doing it that way but let me take you through what it is so again our service name sql server and then indent under that the first thing we specify is the image and that's basically well yeah what's the blueprint for this container in this case sql server and these come from docker hub in this instance unless you specify another repository but in this case docker will go to docker hub and pull down this image and then run up with the following configuration so this section here we're passing in some environment variables so the first one is just accepting the licensing agreement the next one is this system administrator password and then the last one is basically just the flavor of sql server that we want to set up and we're just specifying in this case express you can specify the full flavor of sql server if if you have a license for that so on and so forth again i'll put links attached to this lecture about the documentation that docker provides on how to set up sql server but this is basically all you will need one final thing you will need to specify a port mapping by default when a docker container starts up it's not accessible unless you do a port mapping and basically what that's doing is mapping the internal port within the container to an external port and it basically means you can then connect into it from your desktop and start using it so using this configuration here pretty straightforward we can then access this sql server in the container using this port mapping just using localhost very simple and very straightforward so let's save that off now one other thing i do recommend if you're using visual studio code and this is another reason i really recommend it is this plug-in here docker plug-in highly highly recommend you install it now if you want to install that you just come over to your extensions and then just type docker and obviously this is the same for any extension you want to install and it's probably this top one here yeah it's so pretty much got five stars i've already got it installed absolutely fantastic plug-in and what that gives you basically is the ability to kind of see what images you have already located on your physical machine now obviously as i've been using docker quite a bit i've got these different images that have been downloaded and i have well this is the test test instance of the project i've been running so let's remove that let's get rid of that so i have no containers configured and i have no image but i have images sorry i have images already downloaded so in order to spin this up let's go back to our command line let's clear the screen let's just make sure yeah the file is saved do a quick directory listing and make sure you can see the docker compose yaml file and also make sure that docker is running and the way that we want to spin this up is just type docker dash compose up and then i'm going to specify this dash d which basically just means the command line gets returned back to me if you don't specify that then you basically get loads of status messages and stuff in the the command lines basically then being held by the the running docker containers i don't want that i want it to return straight back to me so if you hit enter what it will do is you can see how quick that was it's actually spun up a sql server already and you can see up here we have a running container now the reason it was so quick in my particular case is because i already have this image on my local machine so when we issued that docker compose command it ran through the file that was specified and looked to see what image it needed and we found obviously you need sql server and then looked in the local image cache to see if we have the latest version we do that's why it was so quick if you don't have those images there it will go to docker hub and pull them down and it might take longer in your case if you don't have those images there nonetheless you can see how quick that was it's just spun up and you get a little green uh arrow there to say that it's running and again the reason i like this tool you can obviously stop docker at the command line and that's just docker stop you can see it's stopped and it's reflected there and then of course to run up you can issue the same command or you can actually right click here and you can stop and restart services as you like so if you prefer doing it that way you can do it that way as well obviously that's the only doc or docker type command you're going to need to run stopping and starting nice and easy and so the last thing we want to just check is that we can actually connect in to that so if you're using windows i'd highly recommend you install sql server management studio which is this graphical tool if you are running windows if you're running linux or mac you will not have access to that so what you can install instead is another extension for vs code called sql server and it basically allows you to do pretty much the same thing that you can do with management studio it's just not quite as nice so in management studio while that's thinking about it i'll show you how to use both of them what you need to specify in order to connect in to a running docker instance is localhost comma and then number the name of the port on the number of the port which in this case is 1433 we're going to select sql server authentication and we're going to give it the password that we supplied in the docker file and that's connecting and what should happen yeah it does thankfully as we connected them we connected them to our sql server instance and if we expand databases you'll see that we don't well we do actually have system databases but they are system databases that we're not going to use we don't have a database for our application but we will create that later so that's management studio which i'm going to use going forward in this video because i just like it if you don't want to install that or you're running on linux or mac then you can install this little plugin here let me just get rid of this remove and once you've installed it again come over to extensions type in sql server [Music] and i think it's this one here yeah so i've got it installed already so this one here yeah it's pretty good it's a bit more basic than the management studio as i say but if you come over to it just add a connection type in localhost comma 1433 database to connect until we don't have any yet so just hit enter we're going to use sql server rather than windows we're going to use essay password and then just the password do we want to save it yes let's save it and then an optional name for the connection and that will go away and it will connect and you can see here it gives us a similar sort of view doesn't give you as many options as management studio but it gives you enough to get you up and running so that's it that's us all up and running with sql server in docker just remember you know you need to run docker before it will work let's come back over to our terminal and again remember to stop it docker compose stop to stop it if you want to do that i'm just going to leave it running in the background for the rest of this tutorial um unless i have to stop it for some reason but for the moment i'm going to leave it uh leave it running so that's it that's the section done um i think we're ready now to move on to actually starting to code up our graphql api all right so in this section we're going to start coding so let's move over to our startup class and we're going to begin in here now the first thing we're going to actually set up is access to the dotnet configuration layer now the reason we need access to that is because we need to read in config and specifically we need to read in a connection string that we will that will allow us to connect to our database at some point we're going to store that in one of the app settings json files and the net configuration layer gives us access to those files as well as some other sources which we're probably not going to use but nonetheless it gives us this nice layer of abstraction uh on top of all these configuration sources we can just read in config in that way it's really quite nice now in order to get access to that we're going to access something called eye configuration and we need to use something called dependency injection in order to set all this up so the way we do that is by defining a class constructor for our startup class and into this we're going to expect an instance of i configuration and we'll call that configuration now this is something called constructor dependency injection if you've not heard of dependency injection or you've never used it it can be a little bit confusing but don't worry we're going to explain it if you still look again after that that's okay as well the more you use it the more it will eventually resonate and you will understand it the reason i'm focusing in on it is because it's used so much throughout not just this application but pretty much every dot net application you're going to see so it's worth covering in some detail now the thing i struggled with when starting out with dependency injection was okay um where when we call this constructor where do we actually get where does this value come from and that's really the whole point of dependency injection that system takes care of the where where does it come from and we'll explain that in a bit more detail a little bit later but just trust me for the moment we are going to get something injected in here at runtime and then we need to do something with it so we're going to assign it to something so i'm going to assign it to something i'm going to call i configure it well just call it configuration and it's auto correcting so let's just take out that binder so i'm going to assign it to this and this as yet does not exist and what this is is basically it's just going to be a read only field okay so what i did there was place my cursor in the complaining artifact hold down control and period and that gave us that list and i selected read only field which has generated for us okay and the value that gets injected here is obviously eventually assigned here and we can then use this configuration in throughout the rest of our classes we will get access to and we can you access all the methods on it and we'll do that later we're not going to do that just yet so that's all the code that we need to set up in order to get access to this configuration object but i think it's worth spending a little bit of time on just how that actually works i'm going to move over to some slides now we'll take a look at that all right so let's just move over to my slide deck and we're going to talk a bit about dependency injection so the first thing probably actually it's worth addressing is why use it what's problem is it trying to solve it's not just something that you just do for the sake of it there is a reason for using dependency injection so the real reason is maintainability allows our code to be more maintainable and how does it how does it achieve that well it achieves that by reducing what's called coupling between our components or between our classes so that still doesn't make sense let's step through an example so without dependency injection you would have a situation where you'll have one class which is a fairly common situation and that class needs to use a second class for some reason doesn't really matter why and straight away that sets up a dependency between these two classes class one depends on class 2 basically and what you would typically see and how you would set that up in code within class 1 is you declare a new object and then you'd use the new keyword and then you'd specify the class that it needed to use all sounds perfectly reasonable and if you're writing really small applications with not that many classes to be honest with you it's perfectly acceptable but nonetheless that's what we call tightly coupled and the reason we say that is if we then suddenly decide that class 2 is no longer appropriate we want to use some other implementation what we would then have to do is we would have to go through every class that used it and effectively rewrite this code or replace you know this you know class two with class three now that might not sound like a huge deal but if you think of a really large application with many classes and many classes using each other many dependencies can get quite complex and you'll end up with broken dependencies not being able to be resolved and it gets quite ugly to be honest with you so that's what we're trying to avoid and depends the injection helps us avoid that so let's look at an example with dependency injection so again we have the same class but instead of telling class one that we need to use a actual implementation in our last example class two all we're telling it to use is an interface now an interface you can describe in a number of ways it really just describes a contract of operations or methods that it's going to provide once it has been implemented by something okay and class one is oblivious to what is actually going to implement the interface all it really cares about is that something will fulfill that interface at some point that's all it cares about now you might still ask the question okay well there's still a dependency here well sort of but not really so let's take it a bit further so instead of writing code like this where you knew up an instance of interface 2 which actually wouldn't work anyway you'd get a syntax error what we do instead is and this is what you saw in the code example we would create a constructor for a class one and we would say as part of class one being set up or constructed we are going to expect interface to from somewhere and then it's the job of the dependency injection system to provide a concrete instance for interface two that's the whole point of it and so yes there we go in the example uh the di system will inject a concrete class in this case class 2 into our my dependency parameter now our next question is going to be how does it know that we want class 2 and not something else well that brings us on to the topic of something that we call the service container now all the service container does is map those associations between your interface and the implementation class in this case class two so at the point where we request interface 2 we look to the service container and we see that yes we have to provide an instance of class 2. now the service container we set that up we set these mappings up from within the configure services method of the startup class which is probably going to bring you on to another question in relation to our code but i'll cover that in a second the code we've set up for eye configuration is a slightly different edge case and i'll come on to that in a bit as to the reason why but coming back to this instance here slightly simpler um example if we then decide that class 2 is no longer the implementation that we want to use and we want to use something else all we simply do is tell the service container to change that mapping and at the point where we construct class 1 the new concrete class will be injected at that point so that's where the concrete classes come from all right so let's just summarize it and i've got another bit of a worked example so in the case of dot net 5 the default service container is called i service provider and here's just a little bit more of a an example which is basically just the same information on the previous screen we will define the interface or you can actually define a base class as well so whenever we're asked for any of these things this is the implementation that we give out at the point they are requested and that can be at the point when the class is constructed there are other ways you can inject dependencies but we'll cover that a bit later when we come to the code so just to summarize yes there we go um configure services in our startup class is where you typically configure the service container so let's just go through a few bullet points um yes dependency injection you use an interface that should actually be or base class just correct that so use an interface or base class to abstract the dependency implementation which we've sort of talked about registration of the dependency is in a service container in the case of asp.net it's a service provider and it's usually through the configure services method and i will emphasize the word usually the service or dependency is then injected into the constructor of the classroom that's been used not always we can inject in other places as i've said but for the most part it's the constructor and then just a little bit of extra detail the di framework is responsible for creating an instance of the dependency and disposing of it and that's referred to as a service lifetime and we'll maybe talk a bit about that later now you're probably going to have a question then if we come back to our code and we look at it we go okay that's all really cool and everything but in our concert configure services method there isn't anything it's empty so i'm still confused as to how we know where eye configuration in this case is coming from well that is a fantastic question and it just so happens i have a slide that answers it there are some services that are injected into the startup class or can be injected into the startup class without needing to register them within configure services and as it says only the following services can be injected into the startup constructor when we're using the default i host builder now that i host builder is actually in our program class so we're not really touching that class but because we're using the default i host builder it provides three it actually registers three services for us already that we don't need to register ourselves in configure services and they are iweb host environment ihost environment and eye configuration okay so it's kind of taking care of that step for us in every other instance where we're using dependence injection we will need to register the services with the service container from the thinking the configure services method and you will see that as we move through the rest of the course so again here's here's the code we've already pretty much written and yes i configuration in the startup constructor and it's just injected at runtime without us having to do anything else so it's a little bit of an edge case a bit of a weird one to start with but it was the first code that we needed to write that required dependency injection so that's it for the slide layer that's really it for this section that's it for all for the code all we really need to do is let's just do a net build just to make sure everything's looking okay actually let's save that first and let's do a dotnet build and yes there we go we get zero warnings so that's cool we will now move on to the next section where at some point we will make use of our configuration layer all right so in this section so short section we're just going to set up the first of two models in our application so we're going to set up our platform model here and it's really going to call our primary model and we're going to have a child commands model that will relate to it at some point in time so within our back in our project just click in the root of our project and hold a new folder and we're going to call it models and into that you'll right-click new file and we're going to call it platform platform singular dot cs now this is probably about as simple a class as you're going to get so um nothing too challenging in here so namespace commander gql and it's in our models namespace and then it's just a public class called platform okay and our class is going to have a number of properties so to define properties you can kind of do in a shortcut kind of fashion if you just type prop and then tab that brings up this kind of template and the first property that we are going to define is in fact an integer so you just tab over and give it a name and we're going to call this id which unsurprisingly is the id of this particular class the next property is actually going to be a string and we're just going to call that name and that's just going to be the name of our platform whatever we choose that to be sold.net docker ubuntu doesn't really matter and then the final property we're going to set up i'm just including this just to provide an example for something that's going to come into play a bit later down the line so you might go why are you adding this in here it it will become clear a bit later on but we're going to add another string property and we're going to call it license key all right now we're not quite done yet because what we want to do is we want to define some annotations or characteristics on these properties so we may push this down to our database which is called the migration i'll cover that a bit later we want to basically tell our database how we want this data to be stored and any rules around it and beyond that not just at the database level from an application level we want to provide these annotations as well so that we know what constraints if any we have on these properties so the first one i'm going to define is key which basically says this attribute is a key not surprisingly now we probably don't actually need to do that uh entity framework kind of takes care of that for us but from a non-database perspective it's probably worth having that in here now you'll see it's complaining and all we do is control period making sure the cursor is in the offending article and it will give us a list of resolutions and we just want to bring in this namespace component model annotations and only other one we want is to specify that our name attribute is required okay so it cannot be null and then license key can be null because some of our platforms may or may not have license keys and to be honest with you that's about it that's all we need to do for our platform model we will be building more later and we will be adding to this as we move through the course but for now that's our first platform model done and that's this section done as well okay in this section we're going to set up our db context so what it might be worth doing actually is just doing a little bit of an architectural revision of our application architecture just to kind of review where we're at so we have a program class we have our startup class which we will continue to work with we do have a request pipeline we've not yet added either graphql or web sockets to it so just ignore that for the moment um we've set up our first model our platform model and now we're coming on to the the data access class or the db context which is really part of this thing called entity framework and all entity framework is is something called an object relational mapper and what that allows us to do effectively is map our internal data or models uh down to a persistence layer in this case we've chosen sql server and the db context basically acts as that mediator it almost acts as a an in application representation of the database and it maps or models them to the database so that's where we're at this is what we're going to focus on as part of this section and just to label the point if it wasn't clear already what we've done so far and indeed what we're going to do in this section really doesn't have anything directly to do with graphql that comes a bit later you would be doing this exact same stuff if you were writing a rest api or some other application.net that needed to access a database this is non-graphql stuff just at this point totally generic cool so let's come back over to our application and we're going to put our db context into a different folder and so new folder in the root of our project and i'm going to put it in a folder called data and then in our data folder i'm going to right click that and do new file and i'm just going to call it app bbcontext.cs all right so again let's define the namespace which is command or gql and this times data and i'm actually going to we're going to bring in some namespaces but i'm just going to actually manually break put these in at the top because this is going to make the flow of the code i'm going to type out a little nicer so the first namespace we need is microsoft entity framework core because we're going to inherit from a base class called db context and that is where we can reference that from another thing we're actually going to reference is a one of our internal areas or internal name spaces so commander gql and models because we're going to actually make use of our platform model and you'll see how that manifests in a minute so we are going to find a public class app dv context and as i said we're going to inherit from a base class called db context okay and again remember back to when we talked about dependency injection we talked about interfaces we also talked about base classes this is basically a base class and you'll see how this manifests later on in fact the db context is something that we inject all over the place throughout this application so just stick a pin in that but bear in mind and then we're actually going to specify as well a class constructor so public and then just give it the name of the class db context and we're going to expect some db context options and we'll just call that options and then we're going to use this base keyword and we're going to pass in those options to the base class effectively and that's all we need to do at this point in time so because we're inheriting from a base class we do need to put this constructor in so that if we do want to pass stuff in at the constructor the constructor is already there for us and then all we need to do is set up a property so prop tab now this time the type of property is going to be something called a db set now what's a db set a db set is basically a representation of our model in the database so think about the db context as the database and think about the db set as the table in the database okay it's basically that simple so we need to specify a type and the type is any guesses platform okay so a db set that's going to mirror or represent our platform model down in our database and the convention will be to name it give it the same name but to pluralize it so our model is singular our db set is pluralized so platforms and that's basically it for our db context but we're not quite finished yet so let's just do a quick.net build just to check that we're all on track and there's no errors hanging around okay so that's all good but we're not quite finished with our db context yet we've two other steps to perform the first one is to provide a connection string that it can use which basically tells it where the data base server is that we're going to connect into and then we need to register it for dependency injection in configure configure services so let's do the connection string first now as i've said previously we can provide that anywhere that the configuration system allows us to access but i'm going to use and quite logically i think i'm going to use app settings development json which is basically a configuration file not surprisingly specifically for use within the development environment so within the file it's just a json file make sure you put a comma and then we're going to specify a new area and you can see here we're actually being provided with a suggestion and i'm going to take that suggestion which is connection strings and if you follow this format it just makes a subsequent code a lot cleaner and i'll call that out when we come to it so i really recommend you use this particular naming convention and then we're just going to specify our connection string but first you know as per json we need to give it a name so anything you like so we'll call it command corner string doesn't really matter and then call on and then we actually specify our connection string now this is a connection string for sql server if you've decided to use a different database platform you'll need to do a bit googling to find out what the format of that system's connection string would be but as we're using sql server this is what we're going to be using so the first parameter is server which not surprisingly tells tells us where our database server is located and for us it's just localhost comma 1433. now you've seen this before when we actually connected into our database if you remember this is our database server we don't have any databases on it yet we just have the server so that's all this is specifying so semicolon and then the next parameter not surprisingly is what database do we want to use so we give it any name commands db now this database doesn't exist yet and it's only when we come to migrating all this down to the server that the database will get created but then subsequently when we connect in this is the database that we'll use cool so then the next thing we want to specify is the user id we're going to connect in with and i'm just going to use the sa account that we've used to connect in and then the last parameter that we should be specifying is the password now just a word of warning here typically you wouldn't specify your password in a set in a settings json file like this for obvious reasons if you commit the the code up to github it's readable and all that kind of stuff but for our purposes it's fine if you want to remove uh sensitive information like this from something like app settings json you would then use another component of the configuration framework such as user secrets and that basically stores sensitive information in that way and i've done lots of other videos on that i'll put a link to videos that i've already done that explain how to do that but in the interest of moving this along i'm not going to do that here that's basically it that's our connection string setup and then the last thing we want to do to round off the context is to come back into startup class and to register it in here as a service so the way we do that is by making reference to services here and we will request that we add adb context now this is registering basically our db context with our service container and so we're single to add a dd context and then we have to specify well basically an implementation and we're going to specify our implementation here which is app db context now we'll complain because it doesn't know where that is yet we need to bring in that namespace but we'll do that in a second and then we want to pass over using a lambda expression we want to pass over some options and first one we want to specify is the use of sql server there we go and let's take a new line now this is where we actually make use of our configuration object that we set up earlier on so configuration connection string and then all we simply do is specify i'm just going to close this out the name of our connection string which is this here now because we used this naming convention connection strings what that means is we actually have access to this get connection string method that's basically where the payoff comes if you didn't use that naming convention you could still access your connection string in the file but you'd have to use a kind of long-winded uh convention to get to it so still complaining about an app db context so it's just to a control period to bring that in and that brings in that namespace now it may also have been the case when i was gonna be playing a bit about playing about early on i think it might have been this namespace here that generally doesn't come by default yes so you may have you may if when you're doing this you may get an error under use sql server and again control period to bring in the relevant name space which i already had up here so just make sure that you you know don't worry if if you've got that it's just because i had the namespace included already cool so that is basically um our dbcontext setup we've set up our connection string and we've now registered our db context within our configuring configure services method so it's now registered in the service container so all that really remains to do insofar as this kind of rough area or this rough section is to now migrate all this stuff down to our database and see if everything that we've done has actually worked okay so in this section we are going to migrate what we have done down into our sql server instance now if you don't know what migration is basically the situation we're in now is that we have our code basically so we have our platform in code we have our db context we even have our connection string and yes we have our sql server but they're kind of still a bit disconnected so what the act of migration is doing is basically saying okay we've got our platform model now we want to now represent that in the database and we do that to a process called migrations so that's what we're going to generate now or that's what we're going to do now and it's a kind of two step process but just before we go on to doing that we just need to check that we have one tool set or one set of tools installed which are the entity framework tools for the.net cli that's a bit of a mouthful and the way to check to see that you have those installed is dotnet ef and if you have them installed then you should see something similar to this here yeah so unicorn and some uh you know information about it now if you don't get that then what you need to do is install those and there's a number of ways that you can install it but the way i'd recommend is to install it in this way so you type.net [Applause] tool update global make sure you spell globalcorrectlyglobal.net ef okay and that will actually install actually that's if you want to update so if you don't have them and you get an error when you run.net ef and it said i don't know what you're talking about to install them from you know from fresh this is the command you would use you may encounter a scenario where you have them installed but the net tool set actually recommends that you have to upgrade them to the latest version in which case it's exactly the same command but instead of install it's just as i typed there which i'm used to doing which hence is why i hence why i typed it is this here dot net tool update and that will just update in fact if we run that now it'll probably just say we didn't need to do anything yeah there we go dot net ef was reinstalled with the data stable version so i was already at 502 anyway but that's all good shows you it kind of working all right so using net ef the first thing we want to do is generate a migrations file so we can take a look at it and see what it's going to do before we actually execute it and the way you do that is yes.net ef migrations add and then you just give the file a name so i'm just going to call this add platform 2 db call it anything you like really but it's probably better practice to give it a name that kind of sort of describes what you're intending it to do so in this case we're adding our platform model to our database so enter and what that will do is i'll actually do a build.net build and hopefully if that succeeds which it has done you know it's succeeded by the looks of it now what you will see for those of you who are keen of eye you'll see that a folder called migrations has been created up here and we have a number of files in it now the only one we're really interested in is this top one here which basically describes what is going to happen when we effectively execute this file and you can see it's time stamped and all that kind of stuff now what it's got it's got two methods an up method and a down method and now that method is used for creating stuff and the down method is used for kind of rolling back changes which you can do with migrations it's quite a powerful system so you can see here we're going to create a table the table is going to be called platforms and that's really been lifted from here in our db context okay and then it's going to create a number of columns an id column which is also going to be an identity a sql server identity with a seed of one and an increment of one a name column of type string is specifying it as an n-bar char and nullable is full so we have to have that and then finally license key which is this kind of weird property we've specified for a use case later down the track and that can be nullable so that all looks good i would suggest whenever you're migrating stuff down that you take a quick look at the migrations file and just give it the one silver because sometimes it's usually pretty good but sometimes it can do some kind of weird stuff especially as you get more complex so that all looks good to me so we'll just close that down and then just to label the point if we come back over to here you'll see and we refresh this you'll see that just because of you know run that that step and generated a migration file it's not done anything there's no database here yet that happens in this final step and that's simply again.net ef not edf database update and that actually executes the the the changes that we want now if you're using while that's happening if you're excuse me if you're using visual studio then you'll have to issue these commands using the package manager console and they are slightly different i will put what those commands are in the appropriate resource section of the video and you can check those out but that looks that was good so again it runs a build which we expected it to succeed anyway but it looks like the actual migration step was successful as well and the easiest way to check that is just to refresh our databases and you can see yep indeed we have commands db created and again just to remind you where that came from that's when we specified the name of the database in our connection string and then if we look a little bit further we should have two tables there's one table called ef migrations history which is used by entity framework so we don't need to really bother about that but the one we are interested in is this platforms table and if we expand it a bit further you can see what columns it has it's got an id column a name column a license key which looks pretty good so that's modeling no pun intended that's mirroring maybe that's a better expression mirroring what we have in our actual code class cool so that's really the fabric of our data base connection type stuff set up so if we just review our architecture i think we're in a pretty good shape um so we've set our model we've set up our db context we've registered it in our startup class so it's available when we need to use it elsewhere in an application so yes we are basically done with this kind of section and we're ready to move on all right so in this section this is where it starts to get interesting well hopefully you found it interesting so far but this is where we're going to dive into graphql proper so over in our project just right click in the root of the project and we're going to create a new folder and we're going to create a new folder that's going to hold all our graphql artifacts and we're just going to call that graphql now actually before we even begin coding it might be worth just revisiting our architecture although we've just gone over this in the last section i just want to take you through what we're actually going to build now so this is what we did in the last section as you've just seen but now we're actually going to introduce a query object or a query type as part of our schema into graphql and as i said in you know the overview of graphql you need a query a root query type entry point it's mandatory so that's where we're going to begin and what we're going to do is we move through we're going to use a client we're going to use a couple of clients actually to query the query the api so yes i'll take you through that as well http post request comes through hits the query we're going to hit our db context and return the data back as a http response so we're going to set all this up in the next few sections so let's get started so yeah back over here in the project right click the folder and we'll do a new file and we're going to call it query.cs and it's a relatively simple class well there's a couple of interesting concepts in it nonetheless so as usual we'll introduce what namespace it's in so it's in commander gql and it's in graphql and then it's just a public class called query so relatively straightforward so far now our query class is going to contain a number of methods that return a queryable result that relate to the things that we want to pull back so just a number of methods we're going to start with one and this method we're going to return back all our platforms basically but the stuff we did in the last section effectively so public i queryable applies the cube and as we don't have any name spaces at the top here we're going to get lots of sort of errors and it's going to expect to return platform and we're going to call this method get platform now this naming convention is actually quite important i'm not going to delve into it too much now we'll cover it a bit later but just use this convention for the moment get and the resource that you want to return back now just coming back to the the topic of dependency injection with the hot chocolate framework we've done something really interesting here and they are allowing you to basically retrieve the db context service as part of this method call rather than injecting it in through the class constructor so we're going to follow their recommendation in their convention and the way you do that is square brackets service and you'll see when we bring in the namespace you know that this is actually coming from the hot chocolate framework and then app db context and just give it a name context so the dot net depends injection framework it only supports constructor dependency injection which i kind of showed you in the slide where this is kind of something slightly different you're allowing um i suppose effectively a dependency to be injected through the method which is a valid approach by the way you can you know other frameworks do support that out of the box so we're getting that with hot chocolate which i think is quite interesting and then let's just clear up the the errors we've got so we're going to bring in the link namespace so again place your cursor control and period so using link we're going to bring in our platform model cool we're going to bring in this service concept and you can see it's actually coming from the hot chocolate framework and then finally we're going to bring in the db context reference namespace should i say and this is error running out obviously because it's not yet returning anything and it's really really simple we just return the dbcontext and we're going to return the platforms basically so just remembering back over here in data db context it's basically just using the db set that's it really so that's it for our query at this point in time it will get slightly more complex as we move through our examples but for now that is sufficient but we're not done yet with wiring up uh graphql we have to now not surprisingly move over to our startup class and add a few things in here so what we're going to do in the startup class is we're going to not surprisingly work within our configure services method to set up some services and we're also going to set up our request pipeline in the configure method but let's focus on the configure services method for the moment and we're going to add two services as part of this section and the first thing we're going to add is this add graphql server and not surprisingly that provides us with a server and also is really the entry point or there's the beginning of our schema construction so we're going to add multiple we're going to chain multiple uh services here which ultimately add up to a full schema at the end of the day the first thing we need to do is add the graphql server and then the next thing we need to add is the query so add query type and we talked a lot about types in the introduction to graphql so we're going to specify that this is of type query which is just the query class that we created just a few minutes ago and just close that out with some round brackets and i'll need to bring in that namespace which is a commander gql graphql and that's it for the moment i mean this will get more complex as we move through our examples but for now that's all we need to do in configure services now the next thing we need to turn our attention to is the request pipeline so perhaps if we just come back to our architecture you're probably sick of seeing this now but i think it's good as a reference point we need to add graphql to our pipeline so let's just clear that down for the moment and the way we do that is within our endpoint section so we're going to add an end point effectively so we can take this pre-canned stuff out so this was added as part of the project scaffold so we can just take that out and all we need to do is just make use of this endpoints lambda expression and all we do is just say map graphql it's pretty much that easy it's not really anything more difficult than that so that is basically it so let's do a quick.net build just to make sure we don't have any gremlins hanging around and that all looks good so we're kind of done for the coding in this section so in the next section i'm going to take you through how to run this up although that's quite easy obviously and we're going to start using some querying tools to actually play and run with this api okay so we're going to run up our api now and pull back some data hopefully if you've done everything correctly but just before we do that a couple of things just make sure because you might be stopping and starting this tutorial as it is quite long just make sure that your sql server is available and running i sometimes forget to if i'm restarting again at a certain point sometimes forget to restart the sql server so make sure it's there and the other thing we want to do and i can't remember i'm losing my losing my mind a little bit i can't remember if we actually put any data into our database so let's take a look i don't think we did so let's look at our platforms table and we can do edit top 200 rows and we don't we don't have any data in there so let's put some in which would be quite useful so let's put in uh net five actually we should probably write it with this i'm just so used to typing.net at the command line that's how i type it.net five docker and let's pick something with windows and we'll put in some junk license key i presume that's a junk license key cool and let's kill that and let's query it to make sure it's in there so select everything from platforms and platforms is a reserved keyword in sql server anyway so we put square brackets around it to kind of delimit it or whatever so that's cool the data is in there um if you want to understand how to put data in using sql you can do something well do use an insert statement so insert into and the table will be platforms and we specify the columns uh we don't specify the id because that's auto-generated so name cool and so we'll just put the name in actually and in values we just put uh test should be fine so i think that's right i'm doing this kind of from memory um actually there you go so it's inserted uh you know this test entry and i'm going to delete it because i don't want something the data is pretty rubbish but i don't want it that rubbish so delete from platforms where id equals five there we go that's gone there yeah get rid of that cool so yeah sql server is running we've got some data in there let's run up our api now so dotnet run [Music] to run it up and you can see here because we've not changed anything we just get the standard port 5000 and 5001 for https and that comes from this launch settings json file which has a number of kind of i suppose you call them profiles depending on which environment you're using as we are using the net cli this is the profile that gets picked and this is the application url great so let's run up a new instance of edge and i'm just going to browse to our endpoint oh yeah so let's just come back here over in our configure method we configured our request pipeline and we added a new endpoint this one here and that basically equates to the following so uh http localhost in fact there's remember that from when i'm testing it but i'll just show you a bit more step-by-step fashion that's the server and then we just type in forward slash graphql to hit that point that we specified now just a bit of a fyi typically on my travels when you're querying graphql apis this is the the standard format generally you'll have the url to the server it might be a bit longer than just you know localhost part port 5000 might be a bit longer than that but always the graphql endpoints typically forward slash graphql and that's what you will use to query against but because we're using the hot chocolate framework the very er kindly provided us with an additional a graphical user interface that we can use to actually run some queries now this is called banana cake pop which is a bit of a strange name the tool's absolutely decent i'm going to use it on and off throughout the tutorial but i'm going to use a tool called insomnia just purely personal preference i actually like it all because it it gives you some i suppose you'd call it intellisense type functionality that this kind of gives you but not not in the in the same way so there's a couple of uh buttons here there's a you can generate queries from here but we can also look at the schema that's been pulled down and you can see here that we have a query and a query type and it has this platform query in here that returns an array of platforms now this platform query just relates basically to this uh query here now as i mentioned we use this get platform syntax uh you'll notice that the word get doesn't actually appear as in terms of the name of the query it's omitted if we decided to call this something else in fact let's do this say blah command c to control c sorry to close that down let's run up again and come back to our endpoint and refresh now i do find with this tool one of the things you do have to do quite frequently is refresh the schema did i say that i didn't save it there you go that's why it's not working so let's save that first and let's run up again that's another hot tip make sure you save everything you do otherwise you're going to look foolish like i did there so let's just uh pull up this and let's refresh it there you go so you can see it's now called black platform which is obviously something we don't want so again just a naming convention call it get platform and then it just uses whatever follows that save that this time control c let's run up again and we'll do a quick refresh of the schema and it should be back to platform so that's basically showing us you know platform and allows us to navigate and have a look at the object attributes or fields as they're called here and we can see you know what types they are as well which is good and whether they're nullable or not which is great now the one thing that is missing here that we will add later is documentation so one of the things i love about graphql is you can actually add documentational elements to your classes and that will then appear as part of the schema so as a developer you don't have to refer to other documentation it's kind of in line with the api so it's very cool and we'll do that a bit later but anyway back back to this tool and let's come back to the the query window and we're going to actually run a query now so in the language we're actually using here is the graphql query language so i'm going to say we want to run a query curly brackets and then if we had more than one query type you know we could select whatever query we wanted but we only have one which is the platform queen and then again we're going to open some curly brackets and then again one of the strong points of graphql is you can specify the fields that you want returned and i just want name an id i'm not going to bring back the license key so let's run that and this is the moment of truth if we've done everything correctly there we go uh we will bring back the the i've just been thrown because i'm seeing this test one here maybe i used the wrong id is that what i did yeah should have been delete id four not five okay it doesn't really matter um so yeah we brought back our four platform objects from within graphql so that's all looking really really good now as i say i actually i'm not going to use this for the most part i'm going to use this tool called insomnia and it gets entirely up to you whether you want to use this or not but i just find it is a very decent tool now this is something else i was playing with so the thing i like about this you can create a number of workspaces which i'm going to do that and a workspace is basically if you if you have a you know like myself here this is a work related workspace i will use it for that if this is my youtube related workspace i can create that so yes let's call this my youtube workspace it's a good one as any and it kind of empties out your workspace so it's completely empty and then there's this concept of environments and that's useful when you have multiple environments so say you have a production environment and a development environment and a test environment and a production replica environment and they all require maybe different api keys to authenticate through you can set that all up in your environments i'm not going to cover that today but it's a really nice feature so in this workspace you just right click you do a new request and we'll just call it let's call it get platforms and it's a post request so pretty much all certainly as far as i've seen all requests that you make to graphql are usually post requests and the body is graphql okay and we'll just create that now you can see here we're already getting an error now that basically is saying that we don't know what the schema is insomnia tries to go away and get the schema and as you can see up here there isn't one so let's just put that in http localhost 5000 graphql and if we do a schema refresh now we'll usually do this automatically but we can force the issue as well you can see that the error's gone and that's kind of cool and we can we might do this as we move through the video we can set up variables and stuff when we come to doing more complex queries but again we're going to specify a query and you can see this is why i like insomnia because straight away it kind of gives you everything that you can do it's really helping you along it's really prompting you along and if you're new to this i actually that's why i'm using it a lot if you're new to the graphql query language it comes in really useful it kind of really helps you out a lot that's not saying the other tool wasn't great but i just found this one is a lot more kind of um helps you along a bit more but it's basically doing exactly the same thing but the thing i like about this is you can kind of see a bit behind the scenes you can add headers so if the api required a key this is where you'd add it authentication is the same thing but ultimately it's doing pretty much the same thing you can do the documentation here as well you can hover over the platform query you can click on that and it will bring up here it returns a platform array or array of platforms and so on and so forth pretty much the same thing doing the same thing brings back the same result so entirely up to you what you want to use but for now i'm going to stick with insomnia so that's our api up and running we've added our first graphql query which is awesome um in the next section we're going to show you one more tool that we're going to use not really for querying but more for navigating our schema it's a visual tool that you can use to see what the schema looks like now our schema is incredibly simple so it's going to not look that impressive but as we build up and it becomes more complex it's a very useful tool so we're going to do that next all right so in this section i promised you that we're going to use graphql voyager but let's just um let's just show you what that looks like so forget our api for the moment i'm just going to show you the tool uh generally speaking so open source um obviously but obviously it is open source so if you just type in graphql voyager and it should take you to the github repo and you can run a live demo so let's do that and i'm not sure what schema this is using but it's you can change the schema it might be starting yeah it's the star wars schema there you go so let's display that and what it basically does is you can kind of see here it gives you a graphical representation of your objects your queries all that kind of stuff so we can look at this person object that's in this particular schema so in our instance it would be platform and you can see all the attributes on it you can see how it's related to other objects or other types within the schema and for complex schemas with many many types and objects and fields this is a really great tool and you can actually you know click on things and it will give you more detail on you know what each of these attributes is and this is kind of the inline documentation i was talking about highly recommend that you do that whenever you're developing an api people using it will definitely thank you for it now the thing to remember here is this schema that's been represented here is exactly the same schema that's been pulled in here which is exactly the same schema that's been pulled into that other tool it's just the same schema and then the later section i'll actually show you how you can generate generate something called an introspection query or run an introspection query that allows you to generate the schema uh and you can actually look at that so we'll do that in a later section down the line if i remember but um for now yeah we're going to set up a graphql voyager in our project so we can use it going forward so back to our project i'm going to control c to kill that down for the moment and we're going to come back to a startup class now just just to remind you back in a project file or cs project file we did add this package reference here which is the reference you need if you want to use graphql voyager so that's already there if you for whatever reason didn't add it please add it now otherwise it won't work what we're going to do next so all we really need to do is within our configure method we're just going to add it really to our request pipeline and the way we do that is app use graphql voyager new graphql voyager options graphql voyager options it needs us to bring in the name space and it's already kind of done that for us but let's just take that out and i'm going to pull that in up the top i don't like doing it that way i like it being as a using statement up at the top it's much cleaner i think and then we're just going to basically specify the end point now the reason i've kind of done it in this sequence is because we're specifying the graphql endpoint here and you'll remember from when we actually used our graphql endpoint all it was was graphql that's it so that's all we have to specify here and we don't need to put in the full you know service name it's just really the end point it's intelligent enough to know that it's just yeah the forward slash graphql component and then the path to graphql voyager so we want to run up and you can obviously specify anything you like here i'm just going to say forward slash graphql dash voyager and that should be good and let me just need to close that off with a semicolon so basically yeah we're just adding graphql voyager to our request pipeline so we're basically just telling it again just to repeat it myself we're telling it where to grab the schema from that's why we need to specify the graphql endpoints we can render that and then we specify the path to where we will display graphql voyager now word of warning is going to look very basic at the moment it's not going to look that impressive but nonetheless it will become more impressive as we uh build our own schema so net run you have saved everything yep cool and then let's just come over here and do another new window and we will just do local hosts and i'll just put voyager here and hopefully there we go that looks familiar there we go so you can see straight away actually it's it's it's giving us some sort of value so but down here and there's drop down you can select the query which is obviously the query type or then the object so we have query well platform query you know as part of our connect root query type and it relates this platform array here relates to the platform object that you've seen already with the attributes that you have now pretty simple but as we build this out and even though we're going to only have two object types platforming commands they're going to have relationships between them we're going to add not just queries but something called mutations which i think i've talked a bit about earlier and also subscriptions as well so this actually starts to become really useful and again you can also see here that both our query and our platform have no description which is a really really bad thing um and as a developer you should be ashamed of yourself if you're putting a an api into the world that has no description especially when you can you know no documentation especially when you can add documentation can it inline so that's something we will cover off a bit later but for now that's this kind of section done our api we've got graphql up and running we have done our first query and i've showed you some query tools but something's wrong something's not quite right i'm going to show you what's not quite right in the next section all right so i didn't just mention that there's something not quite right with the way that we have developed our api today now again here's the query that we've just been running it's all working okay but what i'm going to do is write well i'm going to take this query actually i'm going to run it three times simultaneously let's say using a concept called aliases within the graphql query language so what an alias basically allows you to do is run a section of graphql code multiple times within the same execution sequence and basically what the graphql graphql server tries to do is execute those multiple queries in as close to a parallel fashion as possible it tries to do them all pretty much at the same time and we'll see what happens when we attempt to do that so it's a scenario that actually happens very frequently and very commonly within graphql the more complex queries you have and then especially when you come to querying child objects so we're going to query our platforms and then we're going to potentially query from our commands as well at the same time this issue you're going to see would actually manifest so back over an insomnia i'm just going to do a new request and i'm going to call it parallel platforms [Music] again always a post request graphql for the body click create we get this error because it doesn't have a an end point so i'm going to come back to our previous query and just copy that over and paste that in here and i'll just do a schema refresh and the error's gone fantastic so again query and when i'm talking about aliases basically it just allows you to give the query a name basically so i'm just going to call this first query a and then it's just exactly what we have done before a platform query and then i'm going to select the id and name if you're on this it's fine no problem in fact it's pretty much identical to that okay the only thing you can see differently in the return is we're getting this standard data return but we're then getting the data set for a which is the alias so i'm just going to copy this and i'm sure you're not going to be surprised what i'm going to call it i'm going to call that b and then we'll do it one more time and we'll call the third one c okay so we're just executing the same query basically three times so the graphql server is going to attempt to do this pretty much at the same time so let's see what we get so straight away we're getting some errors we're getting this unexpected execution error uh again again then if we move down we are getting data back but for query a or alias a we're getting nothing argument null same with b and then this time c is executing let's see if we run it again what we get this time same sort of thing we're getting two unexpected execution errors but you can see this time we're getting nothing for a we are getting a payload for b and we're getting nothing for c so it's a bit erratic it's a bit all over the place and we could run this multiple times and you would see that same pattern different things being one of the one of the aliases would be successful and the other two would fail and that's basically done to the fact that the db context we have used is not multi-threaded so it gets ultimately it gets fed this query by our graphql server execution engine and it's saying to it here you go here's execute these three things basically in parallel and db context out the box cannot do that it's not multi-threaded and this is what you get so don't worry we can resolve this and thankfully due to.net 5 microsoft have introduced the concept of a pooled db context factory which is what we're going to use next to resolve this error and it's an error we definitely need to resolve because it's a very common use case from within graphql querying you're going to be doing these kind of multiple queries simultaneously i'll put that in air quotes so yes let's move on and fix this all right so in this section we're going to fix up the issue we have with running this type of query which is you know a query that's almost attempting to be run in parallel or three queries being run in parallel so back over in our application you can actually see that there were a number of errors thrown when we attempted to make the request in the last section so should have probably shown you that let's just kill this and clear the screen so we need to make some changes to our application now interestingly we don't have to make any changes to our db context our app db context class we can just leave that alone but we probably do need to make a change in two places first place is in our startup class and we need to make a change to the way that we register our db context so rather than using add db context we register it using add pooled db context factory so if we actually hover over this we can see what this is actually doing so it registers an idb context factory in the service collection it tells us to create instances of a given db context type what instances are pulled for reuse which is exactly what we want to do and then it just goes on to say registering factory instead of registering the context type directly allows for easy creation of new db context instances so that's all that's really happening here we're just reusing the same db context from a kind of shared pool of resources and so every time we need to make another query it will just get pulled from this resource pool as well and then return back when we no longer need it so it's a really nice addition introduced with dot net five that we are definitely going to make use of here so that's change number one and then change number two is over in our query class and it's really we need to tell our query method that we want to make use of this functionality basically and so in order to do that we have to decorate this method with use not user use db context open brackets type of open brackets and then just a new db context and we need to pull in a namespace from hot chocolate which is hot chocolate dot data let's do that and so basically what this is doing is saying that this particular method has to get a db context from the pool execute the query and then return the context back to the pool when it's finished that's really all it's doing and then here we need to change this to say it's a scoped service now you might be going what is a sculpt service well you may remember in our conversation about dependency injection i mentioned this concept of service lifetimes and this is really just talking to that idea so if we actually i've got a bit of a slide on this if we just take a quick look at service lifetimes we have this concept of a singleton which is the same use the same service for every request which is not what we would want to do in this instance scoped which is we create one per client request and that's basically what we're saying here that we want to have a scoped instance and then there's this other concept of a transient instance which is a new instance created every time which is not what we want in this particular instance so all we're doing back over in our code all we're saying really is yeah in this case we want a scoped instance and that's it so again recap over on startup class we just need to add a pooled db context factory and then back in our query decorate your method with this and it's basically just telling the method how to make use of this concept of a pooled appdb contact pool db context and then just specifying the service lifetime so let's run this up again dot net run and we will attempt to execute our parallel query again so it wasn't running yes it's running cool had errors let's fingers crossed try it this time there we go so we now get results set a result set b result set c so basically using multiple pooled db contexts and that sets us up really well for moving forward with the rest of our api especially in the next section where we're talking about a multi-modal approach in the next section or next full part really we're going to introduce this idea of another model so let's move on to that okay in this section we're going to introduce the concept of our second model to our application and that's going to be our command model so so far we have our platform model which is our parent model and a platform model can have no commands associated with actually or it can have one or more commands associated with it and then when you look at a command object when we build that it can have one platform object associated to it so we're going to introduce the command model as part of this and then we'll need to make some other changes throughout the rest of our application but let's set up our command model now and we actually need to then go and look at our platform model and make a quick change there as well so we'll do that in this section before we move on to changing our db context so back over in our application let's just stop this from running and then over in our models folder we're just going to right click new file and we're going to add a command dot cs file and then as usual specify the namespace command or gql and we're in the models folder and it's just a public class called command autocorrect is great but it can also be really annoying so let's just take that out and make sure it's named correctly cool so we're going to specify a number of properties the first one shouldn't be a surprise it's the id so int id next one prop tab is a string and that's just our how how to so basically what does this command line do next prop also a string and it's basically the command line snippet the actual thing that we want and then we need to specify the relationship between our command and our platform so another property is an integer and this time you're specifying the plat form id foreign key effectively and then we can also specify and i'm going to do this the actual model as well reference to the model the platform model itself [Applause] and i'll just call that platform great so that's basically our properties done now as usual we want to specify some attributes our annotations so this one is a key and we'll bring in the namespace so control period to bring in the namespace and then our how to attribute is different how to property is definitely required so is our command line and so is our platform id cool so looking at that i think that's our command model done so what we then need to do is actually come back to our platform model and kind of make the association the other way we basically need to say that our platform model can have well zero or more commands attached to it so back over here all we need to do is just specify another property and this time it's an i collection of command objects and we're just going to call that commands and one thing we need to do is we just need to set that equal to a new list of command objects and we need to bring in the collections namespace so control periods system collections generic and that should resolve our two issues fantastic okay so hopefully that made sense so that's our two models updated so in the next section we're going to update our db context all right so in this section we're going to progress with adding our multi-model to our application and we're going to update the db context so over in our data folder if we look at our dbe context there's probably a very obvious change we need to make and that's adding another db set so prop db set and we're going to add our command and we're calling it commands so we could leave it like that and we could leave it to entity framework to determine the relationships that our two models have when we come to migrating them down to the database and for the most part that works really well but what i've found from time to time is even just things like naming conventions the way it will maybe name a table in the database is not how i want it to be named if you leave it to its own devices now you could go in to the migrations file and you could edit the migrations file and do things like that i don't really like doing that so instead what we're going to do is we're going to just specify in a little bit more detail the exact nature of the relationship between our two objects within our db context an entity framework we'll use our instructions basically to build out the relationship exactly as we want them so that's what we're going to do now so a little bit laborious but it's worth doing so the way we do that is we override a method which is the on on model creating method so the way in which we do that is protected override void and then it's on model creating and then we specify the model builder and we'll just give that a name model builder so the first relationship we're going to set up is from the perspective of the platform so we'll make use of model builder and we'll specify the entity as i said the entity we're working with to begin with is the platform don't forget the rounded brackets and then we're going to start by saying it has many and we'll use a lambda expression to specify this there's many commands great so nothing too controversial there this one is a little bit more this little bit weirder but we need to specify its relationship almost with itself so we'll see with one we'll use a lambda expression again and we'll see platform and we'll just make that nullable and then we'll then specify the foreign key has a foreign key and again use one final lambda expression p goes to p platform id there we go so that's it quite straightforward and then we just specify using the same kind of construct the same relationship but going the other way from our command so again the entity we're specifying here is our command entity and we're going to say it has one anybody guess what it has one of that's right it has one not platform id it has one platform and it has with many commands i find this a little bit counter-intuitive to be honest with you because we're defining the command relationships so we're almost specifying the relationship as with itself but nonetheless that's what we have to do to do this two-way relationship and then we say has foreign key p goes to p platform id so it's exactly the same as what we have upstairs in this section here so that's really it that's our db context created so when we um you know migrate this down the relationships will be set up accordingly and also we have that you know have this you know have this as you have these relationships from an application perspective as well that's cool so the next thing we really want to do is just migrate all this down to the database so let's just do that now so dotnet let's just clear this so dot net migrations typing is getting worse as i go older add and then we'll just say add command to db and we'll do a build to make sure everything is syntactically correct so the build succeeded that's good and then in our migrations folder we should see another file so here we are and we can kind of take a look at what what it's doing and again i do recommend that you do this so again we're creating a table called commands which is exactly what we want and then you know we've seen this other stuff before the columns that we expect and then we're adding this platform id as a foreign key and then you can start to see this is where we're specifying these relationships between the two tables cool so i think that is i think that's everything that we need to do here so looks good looks okay so the last thing we need to do just clear the screen is dotnet ef database update and all being well it should migrate down so that's a good sign so we come back over to our database and we refresh our tables let's just minimize this that's cool so we have our tables so we have a table called commands typical platforms we have uh our columns in here platform id which is all good another thing you can do here is we can create a database diagram so the reason i'm going to do this so database diagrams new database diagram and then hopefully we'll get the design up we'll just pick the tables that we want the reason i'm doing this is just to sort of show you that that this is the relationship that sql server thinks we have between the two and it's exactly correct it's exactly as we want it okay so i like to do that just to check so that's all looking really good so in the next section what does that mean for our existing query will that mean that we should be able to pull back commands now from our existing query maybe it does maybe it doesn't so the next section we're going to take a look at that okay so in this section i said we're going to test our existing query and see how that works or how that doesn't work or if we messed up or anything like that so let's take a quick look at the query again come over here and basically we're saying uh we're returning basically all our platforms so i'm thinking maybe with the relationships we've set up here maybe it should be clever enough and intelligent enough to pull back our commands as well so actually just before we do that then what might be worth doing is putting some data into our database so let's just do that actually while i remember so let's just refresh do a new query and select everything from platforms just to take a look at what we have in there uh now i'm going to definitely get rid of this test which i should have done last time which i made the mistake and used the wrong id so delete from platforms where id equals four not five okay definitely gone so we've only got three there so that's good um so i'm going to add a couple of commands for dot net 5 why not so we'll be using this id as the foreign key so back over to our commands table let's edit the top 200 rows now again you can use sql statements as i've shown you in the last one of the last sections how to do this but it's just a bit quicker to do it this way so again you don't put anything in id because it's auto populated so i'm just going to say how to build a project really simple stuff build a project and the command line is dotnet build and the platform id is one and then we'll say run a project and it's not proven uh okay cool and then i think what was docker docker was id2 so for docker we'll say um start a docker compose file and we'll say docker compose up d and that's platform two okay so again you know we're not really you know being super critical about the quality of the data we're putting in here but it's really just for test purposes um but you know it's nice to have some data so stop a docker compose file in fact that's probably not particularly a very good description of what we're doing here it's really stopping and starting docker containers by using docker compose but anyway we'll leave it on that just now we can fix that later and let's stop and that's two okay so we've got some data for our commands related to our platforms fantastic all right so let's do a net run everything's saved actually before we do i'm just going to clear down these windows just to give us a bit of room and make sure everything's been saved off which it looks like it has so let's run this cool and come back over to insomnia and i'm going to do a schema refresh that's all good and maybe what we'll do is we will create another let's create another request so new request and we'll call it get platforms and commands which again is one of the powers of graphql you can have these nested objects with the one request and it's really cool so again a post request and it's a graphql query so create that let's copy this from here and we'll put that in here okay so we're going to specify a query and yep a platform query hasn't changed so it's remains the same but you can see now we have a commands collection here that we can iterate through and pull back our command so getting very exciting now so we'll pull back the id for our platform object we'll pull back the name for our platform object and then we'll go into our commands array and we'll pull out the id and we'll pull out how to and we'll pull out the command line fantastic okay and let's see what we get so um not quite what we were expecting we do get back up platforms and we do get back our commands but nothing there okay so what's going on why are we not getting that data back so we do need to make one change over in our query actually in order to allow it to pull back our commands and that is let's stop that over here we obviously have to keep this but we need to decorate this with another attribute and we're going to say use projection what that means is it's basically saying yes you have to walk the graph to pull back any child objects that we have because it's not really explicitly being declared here so we're basically telling it yeah project forward and pull back any child objects now that's not the only place we need to add something we need to come back over to our startup class and i've mentioned this before where we add our graphql type stuff we're going to add multiple we're going to chain multiple commands here or extension methods here to add various bits of functionality so what we need to do after adding our query we need to specify add projections okay and that basically builds that in as part of our schema okay so if we save that off now so again just to recap we went into our query we decorated our method with use project the use projections attribute and then over in startup we added projections as part of our configure services method now that's a very similar repeated pattern you're going to see from time to time you'll typically add something to your query or your mutation but you'll then have to add something here in configure services and i always forget to put things in configure services and it ultimately doesn't work so let's try that again let's run this up again and we come back over here we'll run the exact same query and i'm hoping we should see there we go we are getting data back so it's starting to look a lot better now so you can see down here for windows we're bringing back the windows platform but quite correctly there are no commands so it's just an empty array which is exactly what we want and then for our platforms we're bringing back.net five and then we have two commands and then likewise for docker so we're really at quite a nice point in our querying where you know you you could almost say we're sort of done but there's a lot more things we can do here to make it better and we're going to cover that in the next sections all right so in the last section we added a second model to an application which our commands model which allowed us to retrieve those commands from within our platform query we did have to make some changes to that now before we do anything else i just wanted i thought maybe worthwhile to look at graphql voyager which was the tool we set up the graphical tool we set up and just see what schema looks like now so let's go back to localhost graphql voyager and it should look a little bit different yeah so we have our command model in here now and you can even see the relationships are mapped here as well which is really really nice now we still don't have descriptions on any of our fields or descriptions for our objects or anything like that which we do need to rectify but we'll cover that in a second but as you can see here we just have our one platform query now i want to add another query that will allow us to return our command objects back with the associated platform so not terribly difficult but i think it's useful to do just to embed how to do that so let's kill our server from running and let's come over to our query class where we have you should be familiar with this this is our platform query we're going to add another query in here and it'll look incredibly similar so i queryable and this time it's command we'll bring him back and we're going to call it get command and i'm gonna just say command and i'm gonna say it's a sculpt now this one's more once again and it's just an app context with the name of context and then we're just going to return context but this time we're returning our commands so if we come back over here we're just coming back to app context and we're using this data set commands to turn that back and of course don't forget we need to decorate the method with both these attributes to make use of our multi-threaded db context to save that off looks very familiar and then let's just do a dotnet run and one thing we'll do is we'll come back to draftql voyager and we'll refresh it we should see another query appear here again just bear in mind what this is doing this is going getting the schema and it's re-rendering what it thinks the schema is and you can see here that yeah it's gonna we have a new query called command where you have an array of commands that will come back and looks pretty promising so back over in insomnia i'm going to write a new request i'm just going to call it get commands of course it's a post request graphql of the body create that we'll come back to one of our existing queries do a schema refresh all is good and this time if we type in query you will see our command query has been added and what does that look like that allows us to retrieve or how to it allows us to retrieve our command line and it will allow us to retrieve our platform and we can then specify the name of our platform so kind of the reverse of what we've already done but you know depending on your use case you might want to query this way run that and again yeah there we go so we've got all our commands this time so no redundant no redundant data really we'll just bring back commands and of course they all have to have a platform so it's some it's different to this where we brought back not that one this one here probably did bring back you know our commands but they had no sorry we did bring back our platforms but there was no commands in this instance so you know it depends what you're wanting to do it depends on your use case what you are trying to achieve that's cool wanted to do that just to show you how easy it is to add another query in so um we're going to discuss documentation next okay in this section we're going to talk a little bit about how you document your apis and it's a subject quite close to my heart because i feel every good developer should document their apis i know it's not everybody's favorite topic and you might think it's unnecessary because your scheme is so well defined that it's obvious what it's doing but i can guarantee you people coming to for the first time it may not be may not be as obvious to them so it's a really good practice to get into describing what your objects represent and what the fields within those objects what they actually represent as well because it might not be as obvious as you think so it's definitely worth doing so let's just take a quick look at graphql voyager again and you can see that any tool that that ingests a graphql schema will take with the documentation as well and it will usually display it back to you so insomnia will do that graphql voyager we'll do it banana kate pop will do it really nice it's all built in it's one of the really powerful features of it so there's no reason not to do it really so yeah looking at graphql voyager and selecting our command object there's no description about what it is then there's no description about what the fields are same with the platform and you know you know for example what is a platform what does that represent does it represent all platforms within an organization does it just represent platforms that have a command line interface so again when you actually start looking at it it's maybe not as obvious as you think and you should probably describe what these things are doing so in order to do that we'll move back to our application and we'll just stop it from running and we'll go into our models folder and for the moment we are going to specify our documentation directly on our model classes so let's select a platform class and you just decorate the class with your fql description and then whatever you want to put in here so represents any software or service that has a command line interface so this is useful so it means that you know somebody using this api they're not going to expect to see platforms in here that don't have a command line okay so straight away it's useful now you can see it's complaining so we do need to bring in the namespace for hot chocolate and basically we just repeat this for our attributes as well so i'm just going to do one for license key you decorate the property with graphql description and we'll give it some descriptions it represents um a purchased license for myself for the platform okay or what represents your purchased valid so again useful it's not just you know a historical license key that we've had and it might be invalid but you know that if we're querying this that it's a valid license key so again you know documentation is definitely useful let's save that off and let's run that up and we'll refresh your schema in voyager and we'll see what we get so you can see here straight away our platform object now has a description as we have specified and if we click on our platform object you can see that our license key now has a description as well so it's really really easy to add documentation and i highly recommend you do it in the next section we're going to revisit documentation sort of and we're going to look as well actually at the license key attribute and we're going to have a bit of a discussion around whether we've structured our api in the best way so we'll do that in the next section all right so in the last section we added some documentation to our graphql api which is of course a good thing but just coming back over to our application and looking at how we did that what we did was we went to our one of our models our platform model in this case and we started annotating a class and the properties in the class with this attribute here this graphql description attribute now you might go well that's all all sounds perfectly reasonable but one reservation i have in my mind is that really for me our both our command and our platform models aren't really technically anything directly to do with graphql yes in this instance graphql is making use of them of course but they're not really part of graphql i mean and i said at the start of the video you know this particular part the setup is a totally agnostic part of the setup and it's almost slightly separate to graphql and taking it a step further of you know if we were building a larger application it's entirely conceivable that the graphql part is just a part of it and these models are actually being shared by other services within our application so it could be entirely possible that we could have a bigger application that uses rest and makes use of these models and also makes use of graphql and they too use these models and there might be other things that use these models so the question in my mind is do we really want to be and i'll use this word sparingly do we really want to pollute our internal models that are really nothing to do with graphql do we really want to introduce graphql specific stuff into them doesn't make sense now in the case of documentation you may say that's relatively benign and it doesn't really matter but for me um i don't really feel too comfortable with it and i personally would like to find a way to divorce or separate out still have documentation of course but not have the documentation in our models because for me the models are a separate kind of thing and i'd like to keep them a bit more pure and a bit more divorced or agnostic from the graphql specific stuff i've just taken that a little bit further and i actually think this is a more important point what a model is in my mind is it's an internal representation of the data that we want to store when i say internal i mean internal to the application and even from a business perspective internal to the organization so looking at our license key property which is the reason i actually introduced it in the first place it's entirely reasonable and conceivable that you would want to store your license keys with your platform model that's perfectly reasonable but then would you want to expose that property externally via an api maybe you would maybe you wouldn't but the point is i wouldn't want to directly expose our models by default to a public-facing api or even an internal api i wouldn't want to do that so again i'm looking to find a way to kind of separate out some of our concerns and leave our models purely as internal representation of our data and find some other way to build kind of the graphql layer up on top and you know yes deal with our documentation but also pick and choose what properties we actually want to expose out so that's really where i'm going with this conversation i think it's an important conversation and the way we will continue to build our api in this tutorial is by taking a slightly different approach so that moves us quite nicely on to a bit of a slide deck so let's just it's just one slide so we don't need to get too bothered about it but i want to talk about two approaches that are defined within the hot chocolate framework or the hot chocolate guys define these two approaches in fact i think there's three approaches but i'm just going to focus on these so i want to talk about annotation versus code first approaches now the annotation approach they actually refer to it as the pure code first approach and that's what we have been using so far and what that basically means we're using dotnet codes pure.net types and we are annotating them those types those classes with attributes to provide graphql features which is exactly what you've seen we've decorated our model classes with certain things to provide certain features and we're directly exposing all those properties out via the api so that's what we've been doing first that's what we've been doing so far and that's the annotation or pure code first approach now that might be appropriate for your use case however they define a second approach which is code first which i think i think's a bit confusing pure code first and code first that's why i've opted to use the annotation language i think it makes the distinction a bit clearer and what the code first approaches we start to introduce dedicated graphql schema types and you'll remember from the introduction in the video we talked a bit about types and what that allows us to do is separate or abstract out concerns which is exactly what i'm talking about now you can actually mix both approaches so you can have a bit of both and you know depending on what you're trying to do that's possibly appropriate in a long way describe that we are going to move to a code first approach and start introducing types to deal with the concerns that have raised and if we just come back to our architecture let's do a bit of a an architecture check we'll just show you where that will how that uh overlays on our architecture uh we've done all this stuff you should be familiar with it we've done this stuff we've got query two queries set up we are a root query type and this is what we have so far but what we're going to introduce now is a type and types are basically if you the way i can i think about that are always mapped to models and they provide this kind of graphql specific layer of abstraction so we are going to move on now and create some types all right so in this section we are going to actually introduce types to our application and it'll probably become a bit clearer the word type is a bit confusing actually because it's used in a lot of different contexts and it can get a bit confusing but i think um actually stepping through this example it will become a bit clearer so one of the things i want to do just in terms of organization we have our graphql folder but i'm going to now create some subfolders in the graphql folder that relate to both commands and platforms because well you'll see this as we start building our examples we're going to create a platform type we'll create a command type and when we come on to working with mutations which is you know changing data within our changing data using our api we're going to introduce a couple of other classes related just to our command and our platform and so i feel it's nicer to have those kind of segregated in their own areas so it's really just an organizational thing from my perspective so we're going to be creating a platform type first so in graphql new folder and the folder will be called platforms great and then we are going to create a type within our platforms folder so new file and we just call that form type cs so namespace as usual gql and we're in graphql and we're now in platforms platforms is one of those ones i always tend to spell wrong just so just checking that it's correct and then it's just a public class called platform type but it inherits from something called object type where we tell object type what we're kind of what type of inherit what type we want to kind of build upon basically and we want to build upon our platform model and we'll just singularize that so let me just correct up these kind of um arrows so object type actually comes from this namespace hot chocolate types and then our platform comes from our models area so just to go over this again we're creating a platform type class and we're inheriting from object type which comes from hot chocolate types and we're telling it that we're basically using our platform model is a basis on which to build and then what we do and what we can figure within this class is the things that we want to kind of layer on top of our platform and provide by way of specific graphql functionality so it means we can then remove any graphql specific stuff from our platform model and leave it in a cleaner state and also gives us more control over how we want things to behave well i think it does anyway but one thing you will notice is that the previous approach the annotation based approach it did a lot of heavy lifting for us we actually have to do a bit more work taking this code first approach and so depending on your personal preference it may be a good thing or a bad thing but i feel this is a better approach in the long run for the kind of use cases i encounter anyway so what we need to actually do is override a configure method that is provided by our object type base class so protected override void and it's a configure method and it's kind of pre-populated some stuff for us but basically we want to make use of this descriptor parameter and that's basically what we hook into to kind of configure our platform type class so why don't we put some documentation in at the class level so we use the descriptor and it's quite simple we just use this description method and then we just paste in whatever the description is so what i'm going to do is actually come back over to platform and i'm going to copy this out just to save me typing and i'm going to paste that in here so it's the same but then what i'm also going to do is i'm going to take this out from here okay and i'm also going to delete this because basically what we're going to do is we're going to not expose this property through graphql so it doesn't need a description a graphql description so save that off so basically this is restoring our platform class back to its pure form basically so we don't need to touch that again and we just do everything within here now so basically this is now adding a descriptor to our platform object now if you want to ignore the license field again descriptor and then you just basically hook into a field and we'll use a lambda expression to specify what field is we want to work with and in this case it's license key and then we simply specify that we want to ignore it okay so that's basically saying well it's quite straightforward what we're doing there we want to ignore it now the one other thing that we do need to actually introduce is something called the resolver and i did mention these at the start now what the resolver is actually going to do it's basically telling our platform type how it's going to get in this instance our commands that are associated to the platform and again you know the previous approach all that heavy lifting was kind of done for us we just had to use the projection stuff to allow that to work here we have to do a bit more heavy lifting so the way we do that is within our platform type class we're actually going to specify a sub class which is private so private class we'll call it resolvers and it's in here we tell it how to resolve well whatever we want to resolve so public i queryable i need to bring in that namespace of command i think i'll spell this one query yes variable command and we'll call it get commands and i'm going to bring in this namespace using link and then we're going to specify platform platform sculpt service and this this should look quite familiar actually it's almost similar to the query that we've previously used abby context context let me just bring in these things here so bring in scope service which is coming from hot chocolate and we'll bring in the app db context which is coming from our internal namespace and then all we do is return db context commands which is the data set and then we specify a bit of a where clause and this is just basically using the foreign key to make sure that we only bring back commands that relate to this platform so p platform id is equivalent to platform id now that probably doesn't make well it should make some sense to you hopefully but uh actually think that right um but we'll make more sense because we actually have to make use of this resolver from within our configure method and so we pass over some of the parameters that are required here to in order to pull back the relevant commands so last thing we need to do is do a descriptor use descriptor and this time we want to spend and take a new line because there's a few commands we're going to chain here so field using the lambda we'll go to p commands and then use resolve with and we specify this and then we just need to pass in some stuff using our lambda so p goes to key get commands default and default not quite done so then use db context appdb context and again this looks quite similar to how we've called our queries previously and then i'm going to give it a description as well just uh while we're at it and um this is the list of available commands for this platform it's probably about an obvious one but we'll do it nonetheless we just finish that off cool so let's save that off and the other thing we need to do is come over to a startup class and i always this is the step i always forget to do and in here we need to add that type and we do that saying add type platform type and then we'll just need to bring in that namespace there we go and that should be okay that should be us finished i think so everything's saved i think all we need to do now is do dotnet run and see how we go okay so that's a good sign it's all up and running let's come over to graphql voyager and we'll just take a look at the schema it shouldn't really look any different to be honest with bill uh yeah it looks slightly different yes it will look different because we've removed our license key attributes and we've added a description to our commands uh array so let's go to audio so if all things have worked correctly we still have a description on our platform which is something we added and on our platform you can see we just have id and name we no longer have a license key which is good and if we drill in here you can actually see that this was the description we added to this commands array the list of available commands for this platform and there you go a spelt platform wrong let me just fix that up it's not not the most critical thing but it will annoy me okay i'm not going to bother restarting it but all i am interested in is just making sure that our existing queries continue to work so we're going to use our uh query here let's do a schema refresh and this should just work as it did before there should be no difference there we go and indeed it does so that's all cool so we've added a type in we've used the resolver to basically tell it how we need to resolve our list of excuse me list of commands and other than that it all looks pretty much the same apart from the fact we've taken out some fields and in that way we've cleaned up our platform class our platform model internal model so it's a really good um it's a really good step forward so what i want to do next is add a type for our commands and then we're almost ready to move on to a few other things around querying such as sorting and filtering and then we'll be moving on to further parts where we talk about mutations and subscriptions but that's all coming a bit later all right so in this section we're going to add another type this time for our command so we've created one for platform we're going to introduce the same concept for our command just to keep things a bit more consistent and just to embed embed how we do that so i'm going to kill my server running and back over in our graphql folder i'm going to right click and create a new folder for our commands and in there i'm going to create a new file and we're going to call that command type dot cs and then as usual namespace graphq not graphql command or gql we're in graphql and we are in commands cool and then it's just a public class called command type and we inherit from object type and we specify the type which is going to be command this time cool so let's just bring in the namespace for this which is hot chocolate types and then we're going to bring in command which is our internal namespace and then just as before we're going to override the configure method so protected override void configure tab to complete that out take this out and we'll make use of this descriptor and the first thing we'll do is we'll add a description for the class itself the command class itself and we'll just see i don't know represents any executable and probably a bit obvious but we'll put it in been going on about documentation so be remiss of me not to put it in now one of the things you will notice i think i've said this already is that you do need to do a bit more heavy lifting of course with this approach so again we need to provide a resolver that will basically resolve the platform that this command belongs to so we're working with commands we're querying potentially with commands and we need to go and fetch the platform that it relates to so it's basically what we've done with the platform type we're just kind of flipping it around so private class we'll call it resolver resolvers plural and then we'll just define a method public returns a platform single platform and we'll call it get platform and we're going to get passed in a command we'll call that command and we're then requiring adb context which is a scoped service of type context and we'll call that context okay so exactly the same kind of pattern we've used before let's bring in the name spaces using hot chocolate and our beta namespace so we have our db context and then we simply just return context and platforms this time and we're going to use link expression first or default and then we simply say we just fetch the platform that we need so p goes to p and we will retrieve and we need to bring this in first before this will work so we'll control pd to bring in link so k goes to id that's the platform id goes to the command platform id the foreign key so that's bringing us back the command that sorry yeah bringing bring us back the platform that the command relates to okay can get a bit confusing when you're going both ways so um all right so then all we need to do is make use of this resolver and we'll use the descriptor and i'll take a new line because a few things we want to chain here so the field is going to be c goes to goodness c platform and then we're going to resolve with resolvers as we've done before and then we're just going to specify again using lambda we want to use get platform and then we're going to just pass in default values cool and then we want to use db context it's just of type app context don't forget the round brackets and then we'll uh put some description in as well and this is relating to the platform this is the platform to which the command belongs it's probably a bit of a circular reference but nonetheless we'll leave it there for just now all right cool so let's do a dot net build that's all good and let's do a dotnet run to run up now our schema shouldn't have changed much but let's just interrogate that using voyager should be pretty much the same but it will change we'll have added descriptions in so let's just check that so we've just done our command ah and there's no description there that's interesting ah i know what i've done wrong this is a good example perfect example of remembering must remember to put add the type to the schema didn't do that so and you would do it at some point in the video and there we go done already so command type that's a good example of what happens if you don't do that i'll bring in the right name space which is this one cool all right so let's try that again let's just run it up and let's rerun this i'll refresh this okay and click on command and yes represents any executable command and we've got some description for our platform attributes that's cool that's all looking nice so let's come back over to insomnia and let's re-run our platforms query which was working before so there's no reason why it shouldn't be working now so it's still working okay but what we really want to test is this one here so let's run that okay so we are getting back our commands but we're not getting our platform hmm let's see what we've done wrong let's come back over here i'm going to stop this for a moment i don't think there's anything wrong here let's come back to ah i think i might know what the problem is so if we come back to our query so interestingly we don't actually update our query you probably should have mentioned that when we did the platform type but one thing we can take out is this use of projection because we have explicitly provided resolvers so we will remember we had to use projection because we had to basically tell when we were using a attributes approach and annotation approach sorry we had to tell it project forward and walk the graph to get the child classes we don't need to do that because in our types we have explicitly said thinking maybe that's why we've had an issue so let's um let's test that theory i'm going to take that out from here because we're not using it anywhere now let's save that let's save our query so again i took out the attribute where we use projections and let's run that again i think that's probably what the issue is probably getting confused so let's run this again yes there we go that's okay that's what we wanted yes so cool so it's now using the resolver to pull back our platform and let's just run this just to make sure it's not broken it's fine cool all right so a little interesting tip bit there um when you're using types and resolvers you'd probably need to take out the relevant use projections attribute decoration so that's it for types now we've got a type for a command we've got type for our platform what i want to finish off this kind of querying section on it's not more of a section it's a part large part i want to talk about filtering and sorting and how you can actually add that in really quickly and really easily to your query components of your graphql api to achieve welcome sorting and filtering so let's do that next all right so in this section i did promise we would talk about filtering and sorting and we're going to do more than talk about it we're going to implement it but it's actually super simple using the hot chocolate framework you don't really need to do that much coding at all so i'll show you how to add it and then we'll run some queries to show you how that works so quite a short section not too cold heavy um yeah fairly straightforward so this is one of the reasons i do like hot chocolate it provides us stuff out the box but you do have to opt into it it's not there by default which is nothing wrong with that quite like that approach you've got to opt in to the stuff that you want so how you add filtering and sorting not surprisingly you add it into your query object here or your query class should i say and all you have to do actually is decorate the methods the query methods that you want to have filtering and sorting on it so you just use filtering and you just use sorting it's basically that simple so we'll just copy this so this and we'll paste this in here and of course do not forget that we actually need to add it in here as well so after our types you will just add filtering [Applause] and add sorting so again two places you've got to do it allowing our schema to deal with that and that's really it so we'll save that off do a dot net build would be very surprised if we had any issues and they'll do a.net run let me go so this section will actually spend a bit more time not in the code but actually writing some queries so we're going to write a filter query now and filtering you know is basically just reducing down your result set to filter on something like an id or something like that so let's do a new query new request and we'll call this filter filter query and this is where you know i'm not going to go into too much about writing graphql statements you know that's kind of a separate topic it's a large topic area and i'll put some links to some good documentation that you can take a look at but we want to exercise our changes so i will take you through that of course so again a post request uh graphql query create that and we'll do a sorting we'll do filtering yeah let's do filtering first like we said we'd do that so let's come back over here copy this in to filter query and place that in here the schema refresh should be okay cool i'll do it super simple actually um query and we will let's look at our commands query and what we'll say this is where it's slightly different to what you'll have seen before you can now see we have access to where an order which is basically filtering and well ordering so filtering we'll do it for you and then you just specify what filters you want so open curly brackets and we can you know say platform id so again we're creating our commands but we want to just pull back those for a specific platform platform id and then we'll just say is equal and you've got all these different operators here let me do that again so you can see all the different operators and again i'm not going to go into that here but eq is equal and we'll specify one so i think the platform id one was uh.net so this will bring back just our.net stuff now you can see it's complaining because it's saying you must have a selection of subfuels so that's our query but we need to bring back yeah you know do we want to bring back the id do we want to bring back the platform which we do and bring back the command line and bring back the how-to now you'll see platformers excuse me complaining because platform is an object so we need to define that further and that's why we use the curly brackets to go into that particular object type okay so let's just re-iterate it's a query we're using our existing command query making use of where keyword we're specifying some parameters in this case the platform id and we're wanting it to be equal to one and then we're just specifying the fields that we want to come back we go so cool we just get back our two commands with the uh command sorry the platform id equal to one will not display much let's do that just for clarity it's just called id in that case id so id here should be one there it goes id's one id is one and that's what we were filtering on so you can see how powerful that is and how much you can extend that uh and then we'll just do the sorting query so new requests sorting query again i'm getting used to this now post request graphql body create and we'll just copy and url copy sorting query cool and let's use our platforms this times the platform's query just to show you that it's working on both so query as usual platform's query ah get schema that should resolve now so make sure that's working yeah that's better platform and then we'll say order and we will pass in name and then we'll just specify how we want that to be ordered sending or descending so alphabetically descending again we'll get this complaint here saying that we haven't specified some subfields so we'll just bring back the name i think in this instance run it and you can see here let's put it in alphabetical order if we change that around asc should flip it around there you go so filtering sorting very easy to add i'll leave it to you to kind of experiment with the graphql query language to make use of it and work with it but again very powerful very easy to work with so with that that kind of concludes our section on querying which was a big section and now we're going to move on to looking at mutations which is changing data and then after that we're going to look at subscriptions which is getting real-time data notifications out of graphql so we've actually covered most of what we need to cover the next sections are going to go pretty quick because we've covered most of the groundwork but let's move on to that next all right so in this section we're going to move on to mutations and as i've previously mentioned mutations are when you want to create data or update or delete data so changing data or mutating data which is a fancy way of putting it so before we move on to writing some code let's just do a bit of an architecture review so this should all be very familiar now we have added graphql to request pipeline not quite added web sockets yet and that's for the subscription section we've got our models it's got a data access or dbcontext class sql servers in place we've finished our query queries we've done all this stuff we introduced types to abstract of a graphql specific stuff from our models and yeah this is where we're at basically so what we're going to do next is add a mutation to our mutation class to our schema and we're going to then add individual mutations for adding a platform and adding a command and as part of that we're going to expect some inputs so we're going to have an input class for each one of those mutations and a payload which is basically the result set so input and output or as its name to your payload which is the kind of language used within graphql so all will become a bit clearer later as we you know become very clear in momentarily because we're going to move over to the code now so back over in our application i'm just going to kill running server i'm going to clear that and i'm going to clear this down so the first thing we want to do is over in our graphql folder i want to add a new root mutation type so mutation dot cs and as usual namespace and it's command of gql graphql and it's just a public class called mutation all right and as i said we're going to create two methods in here one for adding platforms and one for adding commands so the first one we're going to do is platform so it's a public and it's going to be a synchronous method called this time so we use the async async keyword and of course it's going to return a task of type now we don't have this type yet but again coming back here it's going to return a task of type payload or add platform payload so let's give it that name now add platform payload and we'll create these in a minute we'll create this in a minute and as well as the input class that we require the name of the mutation is just add platform async and as inputs you're going to require an add platform input which again does not yet exist and we'll just call that input and i'm going to take a new line and we're going to expect a scoped service which is our db context basically our app db context and we'll just call that context okay and i think i'll spell that wrong text there we go scope service okay so we've got quite a few errors going on here because we need to bring in quite a few name spaces so let's bring in task first so threading tasks we don't have either of these yet so they'll remain errors for the moment so bring in sculpt service from hot chocolate and we'll bring in db context there we go another thing we need to do before i forget is we need to decorate our method with the usdb context attribute so use db context type of and then it's just app db context so again that's just to make use of our multi-threaded or multi-threaded db context so bring in hot chocolate data as well all right cool so before we fill out the actual insides of our method which is actually pretty simple i'm going to create these two classes now actually technically they're not really classes they are well they could be they could be classes but we're going to use a new type within c-sharp 9 which is the record type and actually just while i'm remembering i should have some documentation on that here and it just basically simplifies the use of i suppose instead of using classes you can use this record type when you want to use value based equality so it says here in c sharp nine we introduce records it's a new reference type you can use instead of classes or structs records records are distinct and that record types use value-based equality so two variables of a record type are equal if the record type definitions are identical so on and so forth so i'm not going to label that but i'm just mentioning because you may not have seen the use of record before and it's just something new with a c sharp 9 or net 5 or you want to look at it so we could write them as classes it would just be a bit more long-winded the record using a record that's a lot quicker and a bit more elegant so the first thing we're going to write is our add platform and i can see a spelling error already add platform inputs record and then we'll add our ads platform payload so i'm going to add that in the actual platforms folder and again this is why i've created these folders just to keep this kind of collateral separate otherwise it could get a bit messy so add platform input dot cs add platform again i always spell this wrong platform input okay cool and then over here it's just namespace as usual and we are in command or gql we are in graphql and we're in platforms and it is literally one line of code so it's just a public record add platform input and all we're expecting is an input is a string of label that's it that's simple and just to remind you when we're creating a platform we don't provide the id obviously because that's created for us and within our graphql environment we're not wanting license key and we could potentially pass in a list of uh or a collection of commands at the point where we create a platform that's feasible we're not going to do that here we're going to keep it simple so we're just going to create a platform with a name so back over to our platform uh add add platform input record yep that's all we need to do so remember to save that and then we're going to add something very similar but this time for the payload so again we are expecting a add platform payload as an output let's just bring this namespace in so it's from that so that should resolve down cool so we just need to do this one now so back in platforms folder right click new file add platform payload.cs and we're going to use a record as well but before we do that just namespace command or gql graphql platforms and its record public record public record ad platform payload and we're just expecting to return a platform we'll call it platform cool i just need to bring that namespace in and that should resolve down so we'll save that off now and we'll come back over to our mutation fantastic so inside our actual mutation where we do the work effectively it's not really that complex to be really honest with you first thing we're going to do is just create a placeholder platform so we'll just call it save our platform equals new not using soft equals new platform and we'll just give some values i'm going to bring this namespace in so we get use of the intellisense and the only thing we are going to populate is the name and we're going to make that equal to input name we don't actually need the semicolon that we need that there all right so we're just creating a new platform that we're going to then pass over to our db context context we're going to go to our platforms data set we're going to add the platform to it now at this point we've just added a newly created platform object with input that we've been given to our db context it's not been saved down to the database so in order to do that we need to say save changes so we're going to use an asynchronous save change method so await context save changes async fantastic and we're not quite finished because we do need to return the payload so return new add platform payload and we're just going to return the platform that should be us done okay so let's do a net build ah no it's not as done there you go i keep forgetting we've got to come over to startup and we've got to add our mutation type so add mutation type and it's the mutation class where is it here amputation okay and that should resolve because it's in the same space as query so that all looks good so let's save that let's do a net build and hopefully we get two errors so let's have a look we've done something wrong here put the semicolon in let's try that again okay we're all good okay so that's the coding done so in the next section we're going to test our mutation to see if it works so fingers crossed all right so in this section we are going to test that our mutation actually works to add platforms well ultimately to the back end so let's do a net run not rub i wonder what would happen if we type that okay so dot net run and our api is up and running that's cool if we come over to voyager we'll do a quick refresh to pull down the new schema now what you can see here don't panic it basically will display a query view and now you can see here we have a mutation view so we click on that you can see yes we have a mutation now with our add platform well mutation in it and if you click on that it basically takes you over to what it is that we have an input and we have an ad platform payload as an output if you click on this little arrow it will tell you uh what the input is and then it will even expand it now you can see here that we probably should be putting in descriptions and documentation here which i would leave that to you to do is a bit of homework but it's definitely something you should be putting in here not going to do that just here just to move things along so yeah we have a mutation returns on our platform payload type that is basically just maps through to platform object so that looks good let's come back over to insomnia then and test this out so what we're going to do first of all these are all queries so i'm just going to create a new folder i'm going to call these queries and this is just a bit tidy up to be honest with you you don't need to do this if you're not really too bothered i'm just going to do it just to keep things nice and tidy all right it's probably a quicker way to do that but uh okay let's minimize that okay just click on it and then new folder and we call these mutations all right fantastic so right click new request and we'll call this add platform now again i'm just going to label this point we've been making post requests even for our queries no different here it's just a post request with a graphql body so just just again just to kind of label the point with rest apis if you're used to using rest typically you'll use get to read data you'll use post to create data put in patch to update and delete to delete obviously graphql is different as far as i'm concerned everything is just a post request and whether it's a a creation or a reading is basically done within the query body that we pass as part of the graphql body text really so let's just create that just thought i'd make that point um we need to pull in a an end point and again the other point which is probably quite obvious is it's just the same endpoint there's no different endpoints depending on whether you're reading writing creating or you know using commands or platforms it's all just the same endpoint which again i personally quite like okay so we'll just refresh that we've brought the schema down fantastic and unlike queries instead of writing query any guess guesses what we write we write mutation [Music] curly brackets and we have our platform mutation and then to provide input it's rounded brackets not curly brackets tab to provide input colon and then we can provide inside some curly brackets a list of attributes that will be accepted and we only have one in this case which is name colon and then we just provide the string for that so let's say i've been to whenever i'm using linux that's the variant of linux that i use and you can see here it's completing because it does expect us to pull back some fields so bring back a platform object and then we're going to bring back our id and we're going to bring back the name so that should be good so again mutation the name of the mutation input and rounded brackets make sure your rounded brackets and then you just provide the attributes within our curly brackets and it's just a name value pair so again this video is not really about graphql language it's a huge subject area so i'm just kind of scraping the surface to kind of test our api so let's send that over now okay cool so that looks kind of successful so we brought back our data payload with an id of five which kind of makes sense and the name ubuntu fantastic so let's just come over into our database although i'm fairly confident that it's being created but let's just do a new query let's make sure we have the right database selected so it's commands db and it wants to select everything on platforms and bring that back and there we go we've got ubuntu in there with no license key which is great and we can even check that by coming back to our quiz and going let's get all platforms so send over we go and we have our payload return so that's cool so mutation creating data um working so the next one we're going to do is a creation of our commands and then we're going to move on to looking at subscriptions all right so in this section we're just going to add a second mutation to allow us to add commands to our ultimately to our database so it's a very similar pattern not similar it's the same pattern that we've used already for platforms so yeah let's just jump over to the coding and get started now the first thing that was bothering me actually was when i created this mutation file i know it's silly and it makes no difference i just don't like the fact i had a small m so i'm going to capitalize the m the class itself is correct that was just bothering me now before we come on and create a very similar method for adding a command i'm going to first of all create the the inputs and the payload for our command ahead of time so ahead so yeah we're going to do that within the commands folder so first thing we'll do is the input type so new file add command input.cs so you know what this is now obviously it allows us to add stuff to our mutation so namespace is commander gql graphql and we are in commands fantastic and again it's just a public record called add command input and this time it's going to expect a few inputs so how to a string of command line and an integer for plat or id okay now you can name these anything you like i'm just kind of keeping them in line with what exists within our model you don't have to do obviously because we'll take care of that a bit later so just semicolon to close that out so that's all we need to do for our add command input save that off i'm going to do a quick.net build just to make sure that's all okay and we have a warning and startup don't know why that's complaining yeah it's real doesn't it shouldn't be complaining because that's all looking okay okay strange anyway let's keep going and see if that resolves itself not sure why that's doing that um sometimes visual studio can kind of get itself uh studio code should i say it can get itself in a bit of a pickle so we'll add the mutation next so commands new file add commands payload dot cs and just the name space of command gql graphql commands and again it's a public record called add command payload and we're just going to expect it to return a platform or not platform sorry there you go a command called command and i'll just get rid of that and yeah also corrected the command there we go let's bring in the namespace cool all right and then just uh finish that off looks good so that's all done.net build again zero errors that's good and then we'll come back over to our mutation and yes now we're going to add a second method or add command async method that will allow us to make use of those records to create quick command so new line i'm going to put in the decoration first so use db context type of app tv context and then the method itself will look very very similar public async turning a task of type add command payload and we're going to call the method add command async and it's going to request as an input and add command input just call that input new line and scope service db context and we'll call that context cool and then to be honest with you it's really not any different from this it's exactly the same pattern it's just that our command object is slightly more complex so create a temporary holding object we just call it command and that equals a new command and we will see how to equals input how to say command line equals input command line and don't forget the comma and then finally platform id equals input [Applause] platform id and don't forget the semicolon here cool and then in the same way we'll just see context commands add command going to wait on our context save changes async and then we'll just return new add command keyboard and it'll pass back the command fantastic let's do a dotnet build on that yeah this is interesting i think there's maybe something wrong with the the way it's looking for references because we didn't bring in the add command payload or add command input and it's not giving us the errors that we would expect and so even when i put my cursor into your click period it's not giving me any resolutions but the compiler is finding that we don't have the namespace so what i'm going to do and i've seen this before it's going to kill this make sure everything's saved i'm going to reopen it and see if that resolves the issue i find sometimes this can happen and hopefully this will error out once it uh finds its way i'd like to think if not let's bring in the namespace there we go so it's actually found that um yeah found that we've not got the relevant namespace in and it's picked up this is wrong which is good so it's actually at db context it's not add that's better so yeah i think that happens occasionally it can just get itself a little bit confused and i think if you noticed there was an error in startup or i thought there was there wasn't one down there so that's good that's put my mind at rest so that's all good so let's do a.net build again and we should be okay and indeed we are okay cool so that's the coding done and yeah just to say we don't need to do anything else in startup because we've already added the mutation class which contains our new mutation so that's it for our code so in the next section we'll just test this before we move on to subscriptions all right so let's test our command mutation so do a net run to run up and as usual we'll use voyager to see what it thinks is going on so again don't worry it kind of resets the query view just come back down to mutations we should say we have two mutations and it's all looking pretty good so back over in insomnia we're going to add a new mutation request so new request we'll say add command post request graphql create copy in the url and i'll pass that paste down here just keep my refresh cool so we're going to write another mutation so mutation and we should have two now did we do add command some of the things around the brackets we're expecting an input colon curly brackets i'm going to take a new line a little probably pop in one of our inputs so yep it's asking us for how to which is fair enough so how to call on and then oh i don't know um how about perform directory listing keep it super simple and the command line is ls and the platform id is ubuntu so five so not not the most uh elaborate of command lines but it's only one i could think of in the spur of the moment so command and this is as just bringing back the the object that gets created so how to uh command line and i'll tell you what we'll do is we'll bring back the platform as well and we'll just select the name so that should because we've given it an id of five it should pull back the fact that that's been to linux so let's send there we go so again we have a new command in our db with an id of five it's pulled all back and then it's pulled back that it's up into so quite nice and again you can start to see the power of graphql it's very nice we could take our mutations further and you can start adding nested objects from within the mutation so a good example would be yeah creating a platform but at the same time creating maybe one two or however many commands along with it you can absolutely do that i'm not going to show it here just going to take too much time maybe it's something you can look at doing yourself so yeah that's it that's as covering mutations you'll notice i've not used delete or update i think using this pattern you can probably figure that out yourself all you're really going to probably change is in the mutation itself what you're actually doing from a database perspective are you adding a record are you updating it or are you deleting it but the input and payload construct actually remains exactly the same so i think you should be able to figure that out pretty much yourself fantastic so the last part of this tutorial is coming to take a very quick look at subscriptions and how they work and then we'll do a bit of a wrap-up and we're done all right so in this section we are going to be moving on to subscriptions and i like to think of subscriptions as the third leg of the milking stool when it comes to graphql so we have queries mutations and then thirdly we have subscriptions so that's what we're going to be looking at now so let's do a quick architecture check just to see where we are and put things in context so our request pipeline we have added graphql to it for subscriptions we are going to need to add web sockets which is what subscriptions use and i'll talk a bit about what web sockets are when we come to that point the rest of the stuff we're going to kind of skip through as i've gone through it many times this video um yep so we're basically at this point in time so what we're going to add now is a subscription and subscriptions rely on web sockets so before we talk about what websockets are let's just talk a little bit about subscriptions and what they are and why the why you would use them so basically the use case is let's think about an e-commerce application where we have our graphql api that allows us to create orders okay in an e-commerce type environment so order is created you might have other services that want to be notified when an order is created such as maybe a dispatching service or a warehouse management service or something like that so in that case the warehouse management service would subscribe to our subscription endpoint for added orders open orders are created and so when an order is created the endpoint that's subscribed to the relevant event will be notified of that event along with a payload that's basically what a subscription is so it's a real-time event notification it's very useful and we use websockets in a graphql environment to do that what is a websocket a websocket is a fully duplex nailed up connection that's persistent so it's not like a http request that's stateless you make a request and that's it a websocket connection is established and it's there for the duration of the session so it's used for things like real-time applications chat type applications that kind of stuff very powerful so we're going to add web sockets to our request pipeline and we're going to build the subscription so let's get started with that so let's move back over to our application excuse me we'll stop the server running we'll kill this stuff down and as we've done previously for mutations and queries we're just going to go to our graphql folder right click new file and we're going to call it subscription.cs not subscription subscription okay starting with the namespace as usual namespace command or gql and we're going to go fql and it's just a public class subscription [Applause] cool and into that just tidy that up into that we place a basically a method signature that's going to be our subscription endpoint that our graphql client will call and subscribe to so it's just a public and we're going to return a platform object and we need to bring in a namespace in a minute i'm going to call it on platform added so yes just taking a step back what we're going to do here is we're going to change our platform add mutation so that when a product is added using that mutation we're then going to call the subscription event that will then notify anybody that's subscribed to it so we're going to do it just on our platform mutation or platform object so public platform on platform added is what it's called and then we're going to introduce concept of an event message and what is that message it's going to be a type platform and i'm just going to call it platform and i'll just deploralize that and that's going to return a plat the platform okay so let's bring in the relevant name spaces using commando gql models and here as well using hot chocolate fantastic now if you don't like writing it like this if you want to be old school you can write it like this return platform up to you how you want to do it but you can do it either way so i'll leave it like that i actually kind of prefer this syntax for some reason i don't know why we're not quite done with this we need to decorate it with a couple of attributes the first one is topic topics really just relate to the type of subscriptions you can have i'm not going to delve into that today and then the other one is subscribe which is probably a bit more obvious it's just saying that we can use this method as a subscription or we can subscribe to probably more correctly all right cool so we'll save that off that's our subscription done so the next thing i think we should do is move over to startup and we've got two things we want to do or three depending on the way you look at it so in our configure services actually let's move down to in our configure method we want to update a request pipeline to add websockets so add app use web sockets and that's all you need to do you don't really need to do any more than that the hot chocolate framework does all the heavy lifting so that's basically what we needed to do here this is what we've done here cool fantastic so back up to our services we do need to add as usual add subscription type excuse me my voice is giving out now and we just say subscription and then one other thing that you do need to add as well is add in memory subscriptions and this just allows us whenever anybody subscribes this just allows us to manage and track those subscribers in memory if you're moving to a production type environment you may well want to change that out and use our persistence layer to do that management but for now we're just using in-memory subscriptions and that's good enough for us fantastic and then the last place where we need to make a change is over in our mutation and as i said we're going to link into our add platform mutation and we need to add a few more input parameters to our method so i'm just going to take a new line for each of them just to make it look a bit neater so we've got existing ones which is add platform input and our db context so comma and then we're going to add service and what is the service it's an i topic event sender and this is just what we use to actually no surprises send the event and i'm just going to call that event sender and then we should really hand over a cancellation token which is something you can use to well as the name suggests it allows you to cancel asynchronous methods method calls if they are hanging or something like that so cancellation token and we'll just call that cancellation token and that should be as good now we need to bring in a couple of name spaces for itopic event center which is using hot chocolate subscriptions and then we need to bring in the threading namespace for this now we can actually make use of the cancellation token in one of our methods here in our save changes async we can actually pop that in there if you want so let's do that it's probably good practice to do so and then everything else pretty much remains the same we construct our platform object ready to be added to the db context which is then saved down but before we return back this is where we want to send off our event message and actually call the subscription here and notify anybody listening on the other end of the websocket so await and use the event sender send async and this is where we hook into our subscription so name off subscription and we find the on platform added tool and then when we pass over we pass over the platform object and we also use the cancellation token if we need to use that at some point and that's pretty much it i think so again let's just recap we added our subscription type which will get added to our schema uh don't forget to decorate it we needed to add our uh websockets to configure and then we needed to of course add subscription to the schema and we're making use of in-memory subscriptions so let's do a net build and we'll then run it up and in the next section we will test this out so let's just run it up for a prepper in preparation for that so.net run cool so the next section we're going to test this all right yeah so in this section we're going to test that our subscriptions work so the first thing i want to do is bring up voyager again we'll just refresh it to make sure that the subscription has appeared so down here we should see yep a subscription and a list of types that we have access to so that all looks good so now what we want to do is actually trigger our subscription so what we're going to do is we're going to use insomnia to add a platform as we have done before and i've got a mutation ready to go here don't pay any attention to this i'm just playing with it and what we're going to use to subscribe to the subscription is we're going to use the banana cake pop tool so new edge browser and we'll come over here and it's just localhost and graphql now the reason we're doing that is unfortunately insomnia doesn't allow you to subscribe to endpoints because i'm presuming because it doesn't set up a websocket connection whereas banana cake pop does allow you to do that so over in our query window rather than a query we're going to type subscription so you type query or mutation this time we're typing subscription and you can also just point your eyes to the fact that yes banana cake pop is aware of their subscription so on platform added and then we just specify the payload that we want back so id and name let's see you can specify anything you want as per usual with graphql so we'll click start and what you'll see is no results going to get returned because nothing has happened yet but what you will see is this little you know i don't know what you call that timer or something just saying we're waiting we've opened the websocket connection and we're waiting for events so in theory what should happen is when we add a new platform and i'm going to add red hat linux we should see the payload down here and we should also see an event here so let's click send and indeed we do so we get the payload back this time with an id of 12 and likewise we get our event notification over on our subscribed client so again think of the banana cake pop client as a website that web service microservice that's just wanting to listen for certain things happening graphql has a built-in mechanism for doing that so it's really cool it's really quite powerful so with that we are now done with subscriptions as well [Music] well once again we come to the end of yet another video and another long video over three and a half hours long and so congratulations for making it this far and thank you for watching this far now we covered a lot material but there is still a lot of stuff to cover in the world of graphql the two main things that spring to my mind are the relay specification which is a kind of idealized way of implementing graphql which i recommend and the other one is the data loader pattern which speaks to something called the n plus one problem again explain what that is here but it's definitely something that i would recommend we should look at at some point or you should look at in your own time but uh you know with that being said those are the two things that spring to mind are lots of other topics but they are topics very much for another time so once again thank you for watching this far if you liked the video give it a like if you've not done so already think about subscribing and you'll be notified when i make some new videos all that remains is my supporter credits for those wonderful people who support me on patreon so thank you to you as well of course and your names are coming up next so until the next time i make a video stay safe stay well and i'll see you all next time [Music] [Music] [Music] [Music] [Music] so [Music] you
Info
Channel: Les Jackson
Views: 83,414
Rating: 4.9726844 out of 5
Keywords: dotnet playbook, .net, .net core, .net 5, c#, graphql, hot chocolate, api, query, mutation, subscription, pooldbcontextfactory, les jackson, step by step, course, tutorial
Id: HuN94qNwQmM
Channel Id: undefined
Length: 229min 41sec (13781 seconds)
Published: Fri Feb 05 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.