Hey guys, I am Venkat and this is part 6 of web development with blazer series.
I'll include the link to this course playlist in the description below this video. At the moment,
when we navigate to this root application URL, we see the list of employees. This list of employees
are displayed by this index.razor component, and this component is present in the "pages" folder
in BlazorProject.Client, and if we take a look at this index.razor component, notice the list
of employees are hard coded within the component itself. Now, what we want to be able to do is,
retrieve this employees data from sql server database. So, in this video we'll discuss,
how to make http calls to send and receive server side data from a Blazor web assembly app. As we
already know, a blazor web assembly application runs on the client side in the browser, what if
the application needs server side data? Well, it can communicate with the server over http.
In Blazor, we use a class called HttpClient to make http calls to send and receive data
from an API in both the hosting models, that is Blazor web assembly and Blazor server, we
use the same HttpClient class. There are several approaches to use this HttpClient class. A word
of caution though, if not implemented correctly it can lead to problems like socket exhaustion or
failing to handle DNS changes. Going through all these different approaches is too time consuming
and only makes it more confusing, so to keep it simple, let's use the recommended approach. For
real world enterprise apps, the recommended approach is to use IHttpClientFactory.
This approach works with both the hosting models, that is, Blazor web assembly
and Blazor server, it's the same code that we use in both the hosting models which obviously means
it's easier to convert a blazer server app to a blazer web assembly app and vice versa. It also
offers several benefits like providing a central location for configuring HttpClient instances,
it also avoids the problems like failing to handle DNS changes and socket exhaustion. At the moment,
when we navigate to our application root URL "/api/employees", we see four employees here
and these employees are coming from sql server database and this URL that we have here is our
RESP API URL. We built this REST API from scratch in our previous video in this series, again
i'll include the link to this course playlist in the description box below this video. So, at the
moment this REST API retrieves both employees and department data. Now, here's what we want to do,
we want to be able to consume this REST API from our Blazor web assembly app. Now, if we want,
a blazor component can directly call a server-side REST API. However, for separation of concerns,
let's implement a separate wrapper service that uses the HttpClient instance to call server-side
REST API to send and receive data. If you're wondering, why a separate wrapper service? Well,
as I said before for separation of concerns, we do not want our Blazor component to be doing too many
things. When the component needs server side data, t injects this wrapper service and calls it. So,
our natural first step is to implement a wrapper service that calls server side REST API using the
built-in HttpClient class. Let's add a new folder to this project BlazorProject.Client
Name it "services", will place all of our wrapper services in this folder,
so let's add a new "class" file as well, actually we need a new interface, so
let's select interface and let's name it "IEmployeeService". Make this interface "public"
and if we take a look at "IEmployeeRepository" in our BlazorProject.Server and "IEmployeeRepository"
is present in this "models" folder. So, let's open this. This repository
supports all CRUD operations, that is create, read, update and delete employees and search.
Now, if you take a look at this wrapper service that we are implementing, it's just a wrapper,
meaning we want this interface also to support all these operations, so let's copy all these
methods and paste them within our interface right here. We have a lot of compilation errors and all
of them are because we are missing the namespace for both these types - Employee and Gender. If
you recollect from our previous videos in this series, both these types are present in this
project "BlazorProject.Shared", so let's bring in the required namespace by pressing control period.
Our next natural step is to provide implementation for this interface,
so to the same "services" folder let's add a new class file,
name our class EmployeeService, implement the interface IEmployeeService.
Remember, this employee service is just a wrapper service, it's going to use the built-in HttpClient
class to call our server-side REST API, so we're going to inject HttpClient class into this
EmployeeService class using dependency injection, for that we need a constructor, and the class
that we want to inject is HttpClient and this class is present in "System.Net.Http" namespace,
let's bring that in, and let's also call the parameter "httpClient" and generate the
required private field by pressing "control period" and then select this second option.
First, let's provide implementation for this GetEmployees() method and if you
look at the return type, this method is returning Task<IEnumerable> objects, basically the
list of all employees we have in our "Employees" database table. Now, we have already injected
HttpClient instance, so on the injected instance we have GetFromJsonAsync() method and this method
is present in a different namespace, so let's bring in that namespace as well. Now,
what is this GetFromJsonAsync() method going to do? Well, it's going to call this REST API and
retrieve the list of employees, and if you look at this REST API, it returns the list of employees in
JSON format. So, this method as the name implies, GetFromJsonAsync() is going to take the list
of employees in JSON format and automatically serialize them to IEumerable objects.
So, let's specify the same generic parameter here as well, and we also have to tell it the
API endpoint our list of employees are available at "/api/employees". As the name implies,
this method GetFromJsonAsync() is an asynchronous method, so let's "await" its execution,
and since we are using await keyword we, also have to turn this method into an async method.
That's it, just this one line of code, we are done with the implementation of this
GetEmployees() method. I'll provide the implementation for the rest of these methods
in this EmployeeService in our upcoming videos. In addition to this GetFromJsonAsync() helper method,
we also have PostAsJsonAsync(), PutAsJsonAsync() and for deletion it's not DeleteAsJsonAsync(),
it's simply "DeleteAsync", we'll see these methods in action in our upcoming videos.
Our second step is to install this nuget package
"Microsoft.Extensions.Http". This package includes AddHttpClient() extension method. In a bit we'll
see how we are going to use this method, but first let's install this nuget package.
It's in this "Client" project that we want to install this nuget package, so right click on
"BlazorProject.Client" and select this option "Manage nuget packages", make sure you are in
the "Browse" tab and the package that we want to install is "Microsoft.Extensions.Http",
select the package and then click "Install". Package installation complete. Next,
we need to configure http client factory and related services.
We do that in Main() method and this "Main()" method is present in this file "program.cs".
Notice, when I hover the mouse over "services", it is of type "IServiceCollection", so to this
service collection we need to add http client services, for that on "builder.services" we have
AddHttpClient() method and this method is coming from the nuget package that we just installed
"Microsoft.Extensions.Http" and then to this method we specify our wrapper service
interface and implementation. The interface is "IEmployeeService", let's bring in the
required namespace and the implementation is EmployeeService. Now, if we take a look at
GetEmployees() implementation within our wrapper service, notice the path that we have specified
here is only the endpoint "/api/employees", but the full path to get to this endpoint
is right here "localhost:44373/api/employees". So this part "localhost:port number", this is called
the "base" address and we need to specify this as well and we do that right here where we are
configuring our http client services. So, we specify a parameter here, let's call it "client"
"client.BaseAddress" = we can use this "builder" variable to get the base address,
so "builder.HostingEnvironment.BaseAddress" and this is a URI, so let's use a new instance of the
"Uri" class. Notice, when I hover the mouse over this AddHttpClient() method, from the intellisense
you can see it adds IHttpClient factory and related services to the service collection.
Since we're using HttpClient factory to configure and manage http client instances we don't need
this line right here, by the way this line is added here by the Blazor web assembly app template
that we have used to create this project. So, let's keep this line commented. All that is left
right now to do is, inject this wrapper service "IEmployeeService" into our "index" component
and then retrieve data from the REST API. First, let's clean up this component a bit. First of all,
we don't need this huge "LoadData()" method within our component, so let me delete that first. We
are also not going to use this "OnInitialized()" method, we're going to use its async counterpart,
so let's delete this and then notice, when I type "override" and then press the spacebar, we can see
all the methods that we can override. We want to override this OnInitializedAsync() method.
We want to inject our wrapper service into this component, for that we use the [Inject] attribute.
The service interface is "IEmployeeService" and let's name this service "EmployeeService".
This service is present in this namespace "BlazorProject.Client.Services", we can
include this namespace in the component itself if we want to, but a better place is actually
this "imports.razor" file. If we include the namespace in this file, then we can use
the services in this namespace in any of our Blazor components.
Notice, now in the "index" component, we don't have that red squigglies anymore and on this
injected EmployeeService, we have GetEmployees() method which returns the list of employees and
we're going to use that list to populate this "Employees" property within our component.
So "Employees = whatever is the list our service returns", because this component
binds to this "Employees" property and we know this GetEmployees() method is an async method,
so let's "await" its execution. Since we are using "await" keyword, let's turn this method
into an async method and if we take a look at this "Employees" property, it is of type
List whereas this GetEmployees() method returns an IEnumerable objects, so
let's convert this IEnumerable objects to a List objects and for
that we use the ToList() extension method. With all these changes in place let's run our project.
There we go, we see the list of four employees as expected. Now, let's quickly recap the steps. Step
1, implement wrap a service. This wrapper service uses the built-in HttpClient class to call the
REST API to send and receive server-side data. Step 2, install the nuget package
"Microsoft.Extensions.Http". This is the package that contains AddHttpClient() extension method.
Step 3, we use the AddHttpClient() extension method to add http client factory and related
services to the dependency injection container, we do this configuration in Main() method in
program.cs file. Finally, step 4, inject wrapper service in any of your blazor components and
use it to send and receive server data. To inject a service into your blazor component,
we use the [Inject] attribute. That's it in this video. Thank you for listening.