A Full-Stack Web App Using Blazor WebAssembly and GraphQL-Part 1
Tags: csharp, dotnet, blazor, webdev
Published: 2022-02-08 12:18:48

---
title: A Full-Stack Web App Using Blazor WebAssembly and GraphQL-Part 1
published: true
date: 2022-02-08 11:30:19 UTC
tags: csharp, dotnet, blazor, webdev
canonical_url: https://www.syncfusion.com/blogs/post/a-full-stack-web-app-using-blazor-webassembly-and-graphql-part-1.aspx
cover_image: https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zn7iriz8h7moqopqxany.png
---

In this article, we will create a full-stack web application using Blazor WebAssembly and GraphQL with SQL Server as our database.

We will create a MovieApp project. The app will display a list of movies and their details such as rating, genre, description, poster image, and language. It will allow us to filter the movies based on the genre.

The app will have support for authentication and authorization. It will support two roles—admin and user. An admin can add, update, and delete movie data in the application. A user has only read access but can add a movie to the watchlist.

We will then learn how to deploy the app to IIS and Azure app services.

## Tech stack

We are going to use the following tech stack for our application:

- Blazor WebAssembly
- SQL Server
- Entity Framework Core
- Bootstrap
- Font Awesome
- Hot Chocolate
- Banana Cake Pop
- Strawberry Shake

## What is GraphQL?

[GraphQL](https://graphql.org/ "GraphQL's official website") is an open-source query language for APIs. It allows the client to ask for the specific data that it needs. This will make sure that the client controls the data, not the server. GraphQL is not tied to any specific database or storage engine.

## What is Hot Chocolate?

[Hot Chocolate](https://github.com/ChilliCream/hotchocolate "Hot Chocolate demo on GitHub") is an open-source GraphQL server for the .NET platform that allows us to create GraphQL endpoints. It is easy to set up and allows us to deliver our application quickly by removing the need to build a fully-fledged GraphQL server.

## What is Banana Cake Pop?

[Banana Cake Pop](https://chillicream.com/docs/bananacakepop "Introduction to Banana Cake Pop") is a GraphQL IDE that allows us to test the GraphQL server implementations. We can use it with Hot Chocolate or other GraphQL servers. We can also use the [online IDE](https://eat.bananacakepop.com/ "Banana Cake Pop").

## What is Strawberry Shake?

[Strawberry Shake](https://chillicream.com/docs/strawberryshake "Introduction to Strawberry Shake") is an open-source GraphQL client that allows us to fetch data from any GraphQL-compliant server.

## Prerequisites

In this tutorial, we are going to use Visual Studio 2022. Please install the latest version of [Visual Studio 2022](https://visualstudio.microsoft.com/downloads/ "Visual Studio 2022"). While installing, make sure you have selected the ASP.NET and web development workload.

**Note:** [Download and install the latest version of SQL Server and SQL Server Management Studio (SSMS)](https://docs.microsoft.com/en-us/sql/database-engine/install-windows/install-sql-server "SQL Server installation guide").

## Set up the database

The first step toward creating a project is to prepare our database. Open SSMS and create a database named MovieDB.

We will create a Genre table. This table will have two fields, GenreID and GenreName. GenreID will be the primary key for this table.

We will add six genres to this table. Run the command as shown.

```sql
CREATE TABLE Genre (
	GenreID int IDENTITY(1,1) PRIMARY KEY,
	GenreName varchar(20) NOT NULL,
)

GO

INSERT INTO Genre VALUES('Action')
INSERT INTO Genre VALUES('Animation')
INSERT INTO Genre VALUES('Comedy')
INSERT INTO Genre VALUES('Drama')
INSERT INTO Genre VALUES('Mystery')
INSERT INTO Genre VALUES('Science Fiction')
```

Next, we will create the UserType table. This table will have two fields, UserTypeID and UserTypeName.

We will insert the data for two user types supported by our app, admin and user.

Run the command as shown.

```sql
CREATE TABLE UserType (
	UserTypeID int IDENTITY(1,1) PRIMARY KEY,
	UserTypeName varchar(20) NOT NULL
)

GO

INSERT INTO UserType VALUES('Admin')
INSERT INTO UserType VALUES('User')
```

We will create a UserMaster table to store the details of the user for our app. The table will have the columns for UserID, FirstName, LastName, Username, Password, Gender, and UserTypeName. The UserID will be the primary key for this table.

Run the command as shown.

```sql
CREATE TABLE UserMaster (
	UserID int IDENTITY(1,1) PRIMARY KEY,
	FirstName varchar(20) NOT NULL,
	LastName varchar(20) NOT NULL,
	Username varchar(20) NOT NULL,
	Password varchar(40) NOT NULL,
	Gender varchar(6) NOT NULL,
	UserTypeName varchar(20) NOT NULL,
)
GO
```

The table Movie is used to store the details of the movies. The table will have columns for Movie ID, Title, Overview, Genre, Language, Duration, Rating, and the Poster Path of the movie. The MovieID will be the primary key for this table.

Run the command as shown.

```sql
CREATE TABLE Movie (
	MovieID int IDENTITY(1,1) PRIMARY KEY,
	Title varchar(100) NOT NULL,
	Overview varchar(1024) NOT NULL,
	Genre varchar(20) NOT NULL,
	Language varchar(20) NOT NULL,
	Duration int NOT NULL,
	Rating decimal(2, 1) NULL,
	PosterPath varchar(100) NULL,
)
GO
```

Next, we will create the Watchlist table. This table will have three fields: WatchlistId, UserID, and DateCreated. This table is used to store the watchlists of all the users.

Run the command as shown.

```sql
CREATE TABLE Watchlist (
	WatchlistId varchar(36) PRIMARY KEY,
	UserID int NOT NULL,
	DateCreated datetime NOT NULL,
)
GO
```

Finally, we will create the table WatchlistItems. This table is used to store the list of movies added by a user to their watchlist.

Run the command as shown.

```sql
CREATE TABLE WatchlistItems (
	WatchlistItemId int IDENTITY(1,1) PRIMARY KEY,
	WatchlistId varchar(36) NOT NULL,
	MovieId int NOT NULL, 
)
GO
```

## Creating the Blazor WebAssembly application

We are going to create a Blazor WebAssembly app. To do so, please follow these steps:

1. Open Visual Studio 2022 and click **Create a new Project**.
2. In the Create a new Project dialog that opens, search for Blazor and select **Blazor WebAssembly App** from the search results. Then, click **Next**. Refer to the following image.  
 ![Create Blazor WebAssembly Project](https://www.syncfusion.com/blogs/wp-content/uploads/2022/02/Create-Blazor-WebAssembly-Project.png)
3. Now you will be at the Configure your new project dialog. Provide the name of your application. Here, we are naming the application _MovieApp_. Then, click **Next**. Refer to the following image.  
 ![Configure Blazor WebAssembly App](https://www.syncfusion.com/blogs/wp-content/uploads/2022/02/Configure-Blazor-WebAssembly-App.png)
4. On the Additional information page, select the target framework **.NET 6.0 (Long-term support)** and set the authentication type to **None**. Also, check the options **Configure for HTTPS** and **ASP.NET Core hosted** and then click on **Create**. Refer to the following image.  
 ![Providing Additional Information to the Blazor WebAssembly App](https://www.syncfusion.com/blogs/wp-content/uploads/2022/02/Providing-Additional-Information-to-the-Blazor-WebAssembly-App.png)

Now, we have created our Blazor WebAssembly project. Let’s configure it by installing the required packages.

## Configure the Blazor application

We are using the Entity Framework Core database first approach to create our models. We will create our model class in the _MovieApp.Server_ project.

Navigate to **Tools >> NuGet Package Manager >> Package Manager Console**. Select **MovieApp.Server** from Default project dropdown. Refer to the image.

![Package Manager Console](https://www.syncfusion.com/blogs/wp-content/uploads/2022/02/Package-Manager-Console.png)First, we install the package for the database provider we are targeting, which is SQL Server in this case. So, run the following command.

| `Install-Package Microsoft.EntityFrameworkCore.SqlServer -Version 6.0.1` |

We want to create models from an existing database using Entity Framework Tools. Therefore, we need to install the required tools package. Run the following command.

| `Install-Package Microsoft.EntityFrameworkCore.Tools -Version 6.0.1` |

We will implement the JWT authentication mechanism in our app. So, run the following command.

| `Install-Package Microsoft.AspNetCore.Authentication.JwtBearer -Version 6.0.1` |

Run the following command to install the GraphQL ASP.NET Core middleware for Hot Chocolate. This package includes the Banana Cake Pop middleware, which provides us with the GraphQL IDE middleware.

| `Install-Package HotChocolate.AspNetCore -Version 12.4.1` |

To allow the seamless integration of Entity Framework Core into Hot Chocolate, install the following package.

| `Install-Package HotChocolate.Data.EntityFramework -Version 12.4.1` |

To enable the ASP.NET Core authorization integrations for Hot Chocolate, install the following package.

| `Install-Package HotChocolate.AspNetCore.Authorization -Version 12.4.1` |

## Scaffolding the model to the application

Add the connection string in the MovieApp.Server\appsettings.json file as shown in the following. Replace the value with the connection string for your database.

```csharp
"ConnectionStrings": {
    "DefaultConnection": "Data Source=LAPTOP-N6QJKU32;Initial Catalog=MovieDB;User Id=test;Password=sa;"
  },
```

Run the following command in the package manager console to scaffold the models from the database tables.

```csharp
Scaffold-DbContext Name=ConnectionStrings:DefaultConnection Microsoft.EntityFrameworkCore.SqlServer -OutputDir Models -Tables Movie, Genre, UserType, UserMaster, Watchlist, WatchlistItems
```

Once this command is executed successfully, a **Models** folder will be created inside  **MovieApp.Server**  project. This folder contains the DB context class, which will have the name of the database followed by the word Context. Our database name is MovieDB, so the name of the DB context class is MovieDBContext.

Create a folder named **Models** inside the **MovieApp.Shared**  project. Move the classes Genre.cs, Movie.cs, Watchlist.cs, and Watchlistitem.cs from the Models folder of the server project to the Models folder of the shared project. This will allow us to share these classes with both the client and the server.

**Important** : The MovieDBContext contains a default empty constructor, as shown in the following. Delete this constructor. Otherwise, it will throw a run time error.

```csharp
public MovieDBContext()
{

}
```

## Add the Interface

We will use the repository pattern in our application. Add a folder called Interfaces inside the MovieApp.Server project. Add an interface class, IMovie.cs. Then, add the following code to it.

```csharp
using MovieApp.Server.Models;

namespace MovieApp.Server.Interfaces
{
    public interface IMovie
    {
        Task<List<Genre>> GetGenre();
    }
}
```

Currently, we have added only one method to this interface. We will add more methods as we progress with the app creation.

## Creating a movie data access layer for the application

Add a folder called DataAccess inside the MovieApp.Server project. Add a class called MovieDataAccessLayer.cs inside this folder. Put the following code inside it.

```csharp
using Microsoft.EntityFrameworkCore;
using MovieApp.Server.Interfaces;
using MovieApp.Server.Models;

namespace MovieApp.Server.DataAccess
{
    public class MovieDataAccessLayer : IMovie
    {
        readonly MovieDBContext _dbContext;

        public MovieDataAccessLayer(IDbContextFactory<MovieDBContext> dbContext)
        {
            _dbContext = dbContext.CreateDbContext();
        }

        public async Task<List<Genre>> GetGenre()
        {
            return await _dbContext.Genres.AsNoTracking().ToListAsync();
        }
    }
}
```

We are creating a DbContext instance on a per-operation basis using an IDbContextFactory. This is to make sure we do not have any concurrency issues with EF core. We have implemented the IMovie interface and defined the GetGenre() function.

## Add a GraphQL query resolver

A GraphQL query is used to fetch values from a server. It is a read-only operation. Add a folder called GraphQL inside the MovieApp.Server project. Add a class called MovieQueryResolver.cs and put the following code inside it.

```csharp
using MovieApp.Server.Interfaces;
using MovieApp.Server.Models;

namespace MovieApp.Server.GraphQL
{
    public class MovieQueryResolver
    {
        readonly IMovie _movieService;

        public MovieQueryResolver(IMovie movieService)
        {
            _movieService = movieService;
        }

        [GraphQLDescription("Gets the list of genres.")]
        public async Task<List<Genre>> GetGenreList()
        {
            return await _movieService.GetGenre();
        }
    }
}
```

We have injected the IMovie service dependency in this class. The GetGenreList method will invoke the GetGenre method of the movie service to fetch the list of genres. The GraphQLDescription attribute is used to describe the function. This description will be available to the client consuming this function.

## Configure the program.cs file

We will use the program.cs file to configure the middleware for our application. Add the following lines to it.

```csharp
builder.Services.AddPooledDbContextFactory<MovieDBContext>
    (options =>
    options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection")));

builder.Services.AddScoped<IMovie, MovieDataAccessLayer>();

builder.Services.AddGraphQLServer()
    .AddQueryType<MovieQueryResolver>();
```

We are registering our DBContext using the AddPooledDbContextFactory and have provided the connection string path from the appsettings.json file. The IMovie service is created for the scoped lifetime. We have also registered the MovieQueryResolver class with the GraphQL server using the **AddQueryType** extension method.

Then, add the following code at the end of the file to add the GraphQL endpoint to the endpoint configurations. Add this line before calling the Run() function.

```csharp
app.UseEndpoints(endpoints =>
{
    endpoints.MapGraphQL();
});
```

**Note:** You can observe that there is no startup.cs file, which used to be present in the older version of .NET. This is a new hosting model provided with the .NET 6 release. To learn more about it, please refer to [this Microsoft documentation](https://docs.microsoft.com/en-us/aspnet/core/migration/50-to-60?view=aspnetcore-6.0&tabs=visual-studio#new-hosting-model "New hosting model documentation").

## Execution demo

Finally, launch the application and append **/graphql** to the base URL. It will open the Banana Cake Pop IDE in your browser. 

The name of our query method is GetGenreList, as defined in the MovieQueryResolver class. However, when the GraphQL schema is generated, the word **Get** is removed and the method name is generated in the pascal case. Therefore, we have used genreList for invoking the query from the Banana Cake Pop IDE.

## Resource

Also, the complete source code of this application is available in the [Blazor WebAssembly and GraphQL](https://github.com/suresh-mohan/Blazor-WebAssembly-GraphQL "Blazor WebAssembly GraphQL demo on GitHub") repository.

## Summary

Thanks for reading! In this article, we learned how to set up a Blazor WebAssembly app to create a GraphQL server with the help of Hot Chocolate. We created a query and used the Banana Cake Pop IDE to execute it.

In the next article of this series, we will create more complex queries and configure the Blazor client to consume our GraphQL API endpoints using Strawberry Shake.

## Related blogs

- [7 Features of Blazor That Make It an Outstanding Framework for Web Development](https://www.syncfusion.com/blogs/post/7-features-of-blazor-that-make-it-an-outstanding-framework-for-web-development.aspx "7 Features of Blazor That Make It an Outstanding Framework for Web Development blog")
- [4 Easy Steps to Embed a JavaScript Control into a Blazor App](https://www.syncfusion.com/blogs/post/4-easy-steps-to-embed-a-javascript-control-into-a-blazor-app.aspx "4 Easy Steps to Embed a JavaScript Control into a Blazor App blog")
- [Easily Visualize Online Maps in a Blazor Application](https://www.syncfusion.com/blogs/post/easily-visualize-online-maps-in-a-blazor-application.aspx "Easily Visualize Online Maps in a Blazor Application blog")
- [How to Efficiently Group a Large Volume of Data in Blazor DataGrid](https://www.syncfusion.com/blogs/post/how-to-efficiently-group-a-large-volume-of-data-in-blazor-datagrid.aspx "How to Efficiently Group a Large Volume of Data in Blazor DataGrid blog")