Okay.
Our next task is to create a web API controller that's going to be responsible for receiving HTTP requests,
querying our database, and then returning the results in an HTTP response so that we can test this
using our browser.
So let's clean things up at the top and inside Solution Explorer inside the controllers folder.
Let's go ahead and create a new file.
And we do have a template for an API controller.
So let's use this to see what it gives us.
And we're going to call this products controller and press return.
And this gives us the boilerplate for a typical API controller.
And if we compare with an existing controller we have the demo one that was provided, the weather forecast
controller.
We can see that the start of the class resembles what we've just created via the template.
We've got effectively a roots.
How does Net know where to send the HTTP request that's coming in to the correct API controller?
Well, it uses the routing system.
So in order to access this controller we would need to use in our case https colon forward slash forward
slash localhost colon 5001 forward slash API.
And then this controller part.
This is a placeholder for the name of the controller minus the word controller.
So by convention this is if our API controller is called products controller.
Then to access the endpoints in this controller we would use API forward slash products.
Now this next attribute and these are known as attributes.
These things in square brackets is API controller.
And if we hover over this then this indicates that a type in all derived types are used to serve http,
API responses and controllers decorated with this attribute are configured with features and behavior
targeted at improving the developer experience.
That's us for building APIs.
So great.
That's useful.
And we won't talk about this now, but we'll take a look at some of its features a bit later on as we
use some of its features, but it's not going to affect what we do in this controller at the moment.
We'll just leave it in place.
Now inside our API controllers, we create API endpoints and HTTP requests, use HTTP methods, things
like an http get an http post.
If we were going to create a resource, a get would be for a query for a resource, a put would be if
we're updating a resource and delete.
No prizes for guessing what that does, but it would delete a resource of course.
So this one we're going to use the http get attribute, because we're going to get a list of our products
from the database.
Now we return a HTTP response from these HTTP endpoints.
And the way that we do that in dotnet is we return an action result type.
And we can specify what type of thing we're going to return in this result using the angle brackets.
And we're going to return a list of products.
And we need to bring in the using statement for where product has been defined.
So we can where we've got the arrow, we can use our quick fix.
And we can specify we want to use using API entities.
And that gets added at the top here.
So then we'll give the method a name.
And we're going to call it Get products.
And inside here we are going to return.
And at this point we do need to inject our store context and the way that we inject.
I'm just going to demonstrate two ways very quickly about how we inject something into our classes.
There's the old fashioned way where we'd create a constructor using the snippet like so, and then we'd
specify the thing that we want to inject.
In this case, it's the store context, and we give it a name.
And then what we would also do is we'd put our cursor inside context, and then we would use the create
and assign field context.
And this would create a private read only field that we can then access inside our method.
Here I can say context.
And this gives us access to Entity Framework queries.
And it also populates the constructor and assigns the read only field context to list context which
refers to list context.
I'm highlighting here.
So this context is effectively this.
And then we're setting This context using this equals here.
But there is a better way to do this.
And we've got our ellipses here.
So let's use the quick fix and we'll use the primary constructor.
And then we've got access to our context.
And there's no point in this read only line now so we can remove that.
And now this gives us access to our context.
And this is dependency injection.
And when a new instance of our products controller is created which happens when it receives an HTTP
request, then it instantiates a new instance of the store context.
If we didn't define this as a service, then this would not work.
But we have defined this as a service, so this should work.
And then inside our Getproducts method we can return the context and products.
And we can say to list.
And this two list method is going to query our database.
So all of the products in the database, we're going to output them to a list, and that's what we're
going to return from this method.
Let's create another method that will allow us to query for an individual product.
So we're going to say Httpget.
Then we'll add parentheses then quotes.
And then in curly brackets we specify id and this is the ID of the product that we want to fetch from
the database.
And we'll use public.
Again we'll use Actionresults.
And this time we're just going to return a single product and we'll call it get product.
And we need to specify the ID that we're receiving as a route parameter.
So for list method it's going to be API forward slash products forward slash let's say two for instance.
And this integer, the ID that we're passing in as a route parameter that's available here.
We can pass as an argument to our get product method.
Then inside here we can query our database.
So I'm going to say var product equals context dot products.
And then we've got a find method.
And we can find a product that matches that ID.
Now if we hover over the product at this point it will tell us what we're getting from our database
and where we see that question mark.
That means it could be a product, or it could be null, because our compiler doesn't know whether or
not the product exists in our database.
That matches the ID, because it also doesn't know what the ID that we're trying to look for at this
point is.
So it doesn't know if we're actually going to get a product back from the database.
But if we take a look at the find method, then it finds an entity with the given primary key values
and so on and so forth.
But if no entity is found, then null is returned.
So this could be a product or it could be null.
And we need to check to see if that is indeed null.
So we're going to check to see if the product is equal to null.
And if it is we're going to return.
And because we're in the context of an HTTP controller, we can return a not found which will result
in a 404 not found being returned to the client.
Then we can return the product, because at that point we know we have it.
If we do comment out this line actually where we're returning not found, then we do get a warning to
say, hey, product could be null here.
So you do want to check for this, but if we put this line back in then the warning will go away.
So that's our API controller.
And if we go and test this in our browser right now, and let's go back to the tab with the weather
forecast.
And I swap weather forecast for API products and press return.
Then I get an exception at the moment.
And the reason for this, and this is very consistent, is that in when we add a new API controller,
we always need to restart our API server before this is registered with our application.
So let's go back to the terminal.
And if I just scroll down, there's a couple of ways to do this.
We can either use control and R, or we can use control C to stop our application.
And then just use dotnet watch to restart it.
And it does say there we can use control R to restart as well.
So either approach will fix this.
And if we go back to the browser and let's just make that request again, this time we can see that
we're getting a list of products back from our database.
And if I try and get an individual product, let's say product with the ID of three, then we get the
product that matches that particular ID back from our database.
Great.
But we're not going to be using our browser to test our API functionality.
It's fine just for a few get requests very quickly and easy to test, but there's a better tool that
we're going to take a look at to make these API requests.
And I want to introduce that in the next lesson.
And we'll take a look at postman.