Skip to main content

GraphQL API Integration In Asp.Net Core Application

Introduction:


GraphQL is a query language for your API and a server-side runtime for executing queries by using a type system you define for your data. GraphQL can be integrated into any framework like ASP.NET, Java, NestJs, etc and it isn't tied to any specific database or storage engine and is instead backed by your existing code and data.

How GraphQL API Different From Rest API:

  • GraphQL exposes a single end-point or route for the entire application, regardless of its responses or actions.
  • HTTP-POST is the only Http verb recommended by the GraphQL.
  • The client applications (consumers of API) can give instructions to GraphQL API about what type of properties to be returned in the response.

Building Blocks Of GraphQL API:

  • The main building blocks of GraphQL API is Schemas and Types.
  •  A 'Schema' in GrpahQL API describes the functionality available to the clients connect to API. Schema mostly consists of GraphQL Object Types, Queries, Mutations, etc.
  • Types likely to be called GraphQL Object Types. GraphQL Object Types represents the data source types return from API. GraphQL Object Types contains 'Fields' and 'Methods'. Fields are just properties in a class, 'Methods' are used to modify or conditionally change the field values based on client query.

Create ASP.NET Core Web API Project Template:

Let's start to learn about features in GraphQL, its implementation, and its integration into the Asp.Net Core application. Now create the Asp.Net Core Web API template.

GraphQL Nuget:

Open package manager console in VisualStudio to install GraphQL Nuget.
           Install-Package GraphQL -Version 2.4.0

Create Data Source Model:

Data Source Model means which represents a Table class. So add the new folder as 'Models', to that folder add a new class as 'Player.cs'
public class Player
{
 public int Id { get; set; }
 public string FirstName { get; set; }
 public string LastName { get; set; }
 public int CurrentAge { get; set; }
 public string Teams { get; set; }
 public string PlayingRole { get; set; }
 public string BattingStyle { get; set; }
 public string BowlingStyle { get; set; }
}

Create A Data Repository And Register To Services:

A repository is a data access layer, where communication with the database goes. So add the new folder as 'Repositories', to that folder add two files like 'IPlayerRepository' and 'PlayerRepository'.

IPlayerRepository:
using System.Collections.Generic;
using GraphQLSample.Models;
namespace GraphQLSample.Repositories
{
    public interface IPlayerRepository
    {
        List<Player> GetAll();
    }
}

PlayerRepository:
using System.Collections.Generic;
using GraphQLSample.Models;
namespace GraphQLSample.Repositories
{
    public class PlayerRepository: IPlayerRepository
    {
        // later code will be updated
        // to get data from database
        public List<Player> GetAll()
        {
            return new List<Player>
            {
                new Player
                {
                    Id=1,
                    FirstName= "Rohit",
                    LastName = "Sharma",
                    CurrentAge = 32,
                    PlayingRole = "Opener",
                    BattingStyle = "Right-hand Bat",
                    BowlingStyle="spin",
                    Teams="India, Mumbai, Mumbai Indians"
                }
    // display purpose items hidden , while testing add more items
            };
        }
    }
}
Here repository 'GetAll()' method returning all the players(later code will be updated to access players from database).

Register Repositories In ConfigurationServices Method In StartUp.cs:
services.AddScoped<IPlayerRepository, PlayerRepository>();
By default, the Dotnet Core application configured with dependency injection, so the creation of an object to any service or repository classes taken care of by it. AddScoped() represents an object created per request.

ObjectGraphType:

  • 'GraphQL.Types.ObjectGraphType' class represents Types in GraphQL which we discussed as one of the core concepts in GraphQL.
  •  GraphQL is not bound to any specific language or framework, so it can not understand CSharp POCO( Plain Old CLR Object ) classes directly. 
  • So to represent GraphQL Type, CSharp Classes need to inherit 'GraphQL.Types.ObjectGraphType'. 
  • After inheriting ObjectGraphType in the constructor we need to register our own class properties as 'Field' types which is understandable by GraphQL.
Let's implement a type that inherits the ObjectGraphType in our sample. So add the new folder as 'GrpahQLTypes', to that folder add new file 'PlayerType.cs'

PlayerType.cs:
using GraphQL.Types;
using GraphQLSample.Models;

namespace GraphQLSample.GraphQLTypes
{
    public class PlayerType:ObjectGraphType<Player>
    {
        public PlayerType()
        {
            Field(_ => _.Id);
            Field(_ => _.FirstName);
            // description is an self 
            //explanatory extenstion method which is options
            Field(_ => _.LastName).Description("last name of a player");
            Field(_ => _.CurrentAge);
            Field(_ => _.Teams);
            Field(_ => _.PlayingRole);
            Field(_ => _.BattingStyle);
            Field(_ => _.BowlingStyle);
        }
    }
}
  • Here we have a model 'Player' which CSharp POCO classes, which can't be understood by GraphQL directly. 
  • To make 'Player' to GraphQL Type, we have created a new class 'PlayerType' which inherits 'GraphQL.Types.ObjectGrpahType<T>'. Type took by ObjectGraphType is 'Player' to represent it as GraphQLType. 
  • All the properties of 'Player' class returning as 'Field' types which can be understood by GraphQL.

Schema:

  • Schema is one of the main building blocks of GraphQL API. 
  • Schema mainly consists of Query, Mutation, Types, etc. Query in Schema is an ObjectGraphType, but it is like Root or Parent ObjectGraphType. 
  • Schema Query held all other ObjectGraphType of entire application, more or less it acts as a Data Source to clients consuming GraphQL API. 
  • Based on the client's request this Query in Schema serves data.
Let's start to create a Query in the Schema of GraphQL API. In the 'GraphQLTypes' folder add a new file name it as 'RootQuery.cs'

RootQuery.cs:
using GraphQL.Types;
using GraphQLSample.Repositories;

namespace GraphQLSample.GraphQLTypes
{
    public class RootQuery:ObjectGraphType
    {
        public RootQuery(IPlayerRepository _playerRepository)
        {
            Field<ListGraphType<PlayerType>>("players", resolve: context =>
             {
                 return _playerRepository.GetAll();
             });
        }
    }
}
  • Here all players returning under field name 'players' and Field register with 'PlayerType'(ObjectGraphType). 
  • Similarly, all POCO classes which represent a table will have their individual ObjectGraphType(like PlayerType for Player class) and these all ObjectGraphType will be registered as Field type in RootQuery in our application. 
Register RootQuery in ConfigureServices method in Startup.cs
 services.AddScoped<RootQuery>();
Now in the 'GraphQLTypes' folder add a new file and name as 'RootSchema.cs'. By default GraphQL Dotnet Library provides us 'Schema' and 'ISchema' entities, but we are creating custom schema like 'RootSchema' because to consume the benefits of Dependency Injection. Our 'RootSchema' inherits both 'GrpahQL.Types.Schema', 'GraphQL.Types.ISchema' to represent a GraphQL Schema.

RootSchema:
using GraphQL;
using GraphQL.Types;

namespace GraphQLSample.GraphQLTypes
{
    public class RootSchema:Schema, ISchema
    {
        public RootSchema(IDependencyResolver resolver):base(resolver)
        {
            Query = resolver.Resolve<RootQuery>();
        }
    }
}

GraphQL NuGet library comes with inbuild Dependency Resolver. 'Schema' class has 'GraphQL.IDependencyResolver' as property, so that it can resolve all ObjectGraphType it needed.
.
Register Schema and IDependencyResolver in method ConfigurationServices in Startup.cs:
services.AddScoped<IDependencyResolver>(_ => new FuncDependencyResolver(_.GetRequiredService));
services.AddScoped<ISchema, RootSchema>();
'GraphQL.FuncDependencyResolver' implements 'GraphQL.IDependencyResolver'.

Create GraphQL API EndPoint:

Now create a new Web API Controller as 'GraphQLController' and the controller contains only one action method that supports Http-Post verb. In the model, folder add new file 'GraphQLQueryDto.cs' files that represent the post data payload entity.

GraphQLQueryDto.cs:
namespace GraphQLSample.Models
{
    public class GraphQLQueryDto
    {
        public string Query { get; set; }
    }
}
Query property represents data to query the GraphQL API.

GraphQLController.cs:
[Route("graphql")]
public class GraphQLController : Controller
{
 private readonly ISchema _schema;
 private readonly IDocumentExecuter _executer;
 public GraphQLController(ISchema schema, IDocumentExecuter executer)
 {
  _schema = schema;
  _executer = executer;
 }

 [HttpPost]
 public async Task<IActionResult> Post([FromBody] GraphQLQueryDto query)
 {
  var result = await _executer.ExecuteAsync(_ =>
  {
   _.Schema = _schema;
   _.Query = query.Query;
  }).ConfigureAwait(false);

  if(result.Errors?.Count > 0)
  {
   return Problem(detail: result.Errors.Select(_ => _.Message).FirstOrDefault(), statusCode:500);
  }
  return Ok(result.Data);
 }
}
  • Here [Route("graphql")] is route decorator, it says controller configured with Web API attribute routing. 
  • 'GraphQL.ISchema' is a Schema of GraphQL API, the instance of schema was created by constructor injection. 
  • 'GraphQL.IDocumentExecuter' has async GraphQL query executor. On successful execution of IDocumentExecuter returns data. On Error, execution returns an error message to the clients consuming GraphQL API.
Register 'IDocumentExecuter' in the ConfigureService method in Startup.cs:
services.AddSingleton<IDocumentExecuter, DocumentExecuter>();

Fields:

GraphQL is about asking for specific fields on objects on the server. Let's test API by requesting Fields.

Request Query:
query {
 players {
  id
  firstName
 }
}

Here GraphQL Query just looks like almost similar to JSON Object. 'query' is represented as root query. 'players', 'id', 'firsName' are registered Fields in ObjectGraphQLType as below:
// field registered in RootQuery.cs
Field<ListGraphType<PlayerType>>("players", resolve: context =>
{
 // logic to server 'players'
});

// field registered in PlayerType.cs
Field(_ => _.Id);
Field(_ => _.FirstName);

Now test API as below:
We got 500 error status code and error message shows 'PlyerType' has been not registered. I allowed this error purposefully, because to aware that every ObjectGraphQLType must be registered in Startup.cs

Resolve No Service Registered For ObjectGraphQLType:

Now register PlayerType in the ConfigureService method in Startup.cs:
services.AddSingleton<PlayerType>();

Now test API again:

Query Arguments To Filter Data :

In GraphQL we can pass an argument to filter the GraphQL API. Since in GraphQL data is coming based on Fields requested, it is possible to pass arguments to the fields to filter the data.

RootQuery.cs:
public class RootQuery:ObjectGraphType
{
 public RootQuery(IPlayerRepository _playerRepository)
 {
  Field<ListGraphType<PlayerType>>("players", resolve: context =>
   {
    
    return _playerRepository.GetAll();
   });

  Field<ListGraphType<PlayerType>>("filteredPlayers",
   arguments: new QueryArguments
   {
      new  QueryArgument<StringGraphType> { Name = "firstName"}
   },
   resolve: context =>
   {
    string firstName = context.GetArgument<string>("firstName");
    return _playerRepository.GetAll().Where(_ => _.FirstName.ToLower() == firstName.ToLower()).ToList();
   });
 }
}
  • Here we added a new Field with name 'filteredPlayers'. 
  • 'ListGraphType' is collection representation in GraphQL. 
  • Filed takes an 'arguments' as input parameter and its type is 'QueryArguments', here we capturing our argument like 'firstName' which is passed from the client to GraphQL API. Arguments that are captured here will be available from the context of Field.
  • 'StringGraphType' is equivalent to 'string' type in dotnet. 
  • From 'resolve' which is the input parameter of Field, we are getting the value of our argument like 'firstName' from field context. Based on the argument value filter the data and send to the client.
Request query with arguments:
query {
 filteredPlayers(firstName: "rohit") {
  id
  firstName
 }
}

Now test the GraphQL API:

Aliases:

We can observe that field name and API result object names are matching. By looking at the previous result object whose name is "filteredPlayers" is like more self-explanatory which might not look good in the JSON result object for clients consuming the GraphQL API. "Players" looks ideal name for the result JSON Object, but we can not use the "Players" name for argument query because of the normal query without argument using it. So this problem can be overcome by using Aliases names in the query fields. The server will return data by using the aliases' names.

Aliases Query:
query {
 players: filteredPlayers(firstName: "rohit") {
  id
  firstName
 }
}
To test the aliases name, test the API  with arguments query:

Fragments:

A comparison between two records in GraphQL API is very easy. Let's do a comparison using the below query

The query for comparison (without Fragments):
query {
 leftPlayer: filteredPlayers(firstName: "rohit") {
  id
  firstName
  lastName
 }
 rigthPlayer: filteredPlayers(firstName: "virat") {
  id
  firstName
  lastName
 }
}
Now test GraphQL API:
Here in GraphQL API, we are getting comparison data in a perfect way without doing any work at the server-side. But if we carefully observe queries constructed with duplicate fields, which will be tedious if the fields are a high number.

So to resolve these duplicate fields, GraphQL provided an option called Fragments where a set of similar fields will be grouped to a set.
The Query for comparison with Fragment:
query {
 leftComparison: filteredPlayers(firstName: "rohit") {
  ...props
 }
 rightComparison: filteredPlayers(firstName: "virat") {
  ...props
 }
}
fragment props on PlayerType {
 id
 firstName
 lastName
}

  • Here 'fragment' keyword represents GraphQL Fragment. 
  • 'props' defines the name of the fragment. 
  • 'pops on PlayerType' represents a fragment working on which type of ObjectGrphQLType(example from our sample PlayerType is an ObjectGraphQLType). 
  • A fragment was enclosed with set fields grouped. 
  • Inside query we can observe instead of mentioning fields, we have used fragment name prop which dynamically replaces fields at the time of query execution on the server.

Now test GraphQL API:

Accessing Data From Database:

We are going to create a DbContext, code-first approach with an existing database. Let's first install NuGet packages related to entity-framework as below.
        Install-Package Microsoft.EntityFrameworkCore -Version 3.0.1
        Install-Package Microsoft.EntityFrameworkCore.SqlServer -Version 3.0.1
Create a new folder name as 'Data', inside add the new file as SportsContext.cs as below:
using GraphQLSample.Models;
using Microsoft.EntityFrameworkCore;

namespace GraphQLSample.Data
{
    public class SportsContext : DbContext
    {
        public SportsContext(DbContextOptions<SportsContext> options) : base(options)
        {

        }

        public DbSet<Player> Player { get; set; }
    }
}
Register SportsContext in ConfigureServices method in Startup.cs as below:
services.AddDbContext<SportsContext>(options =>
            options.UseSqlServer(Configuration.GetConnectionString("SportsContext")));
Add database connection string in "appSettings.json". Now update the 'PlayerRepository.cs' as below:
using System.Collections.Generic;
using System.Linq;
using GraphQLSample.Data;
using GraphQLSample.Models;

namespace GraphQLSample.Repositories
{
    public class PlayerRepository: IPlayerRepository
    {
        private readonly SportsContext _sportsContext;
        public PlayerRepository(SportsContext context)
        {
            _sportsContext = context;
        }
        public List<Player> GetAll()
        {
            return _sportsContext.Player.ToList();
        }
    }
}

GraphQL Query to test:
query {
 players {
  id
  firstName
  lastName
 }
}
Now test GraphQL API:

Mutations:

GraphQL Mutations represent changing the state of data at the server-side, which means to create or update or delete data. To perform mutation you need to have the root mutation object of type ObjectGraphType. Like RootQuery which holds all ObjectGraphType Fields to fetch the data, we need to create RootMutation which holds all ObjectGraphType Fields to create or update or delete the data.

Let's write logic to add a new item in  'PlayerRepository.cs' file as below:
public Player AddPalyer(Player player)
{
 _sportsContext.Player.Add(player);
 _sportsContext.SaveChanges();
 return player;
}
IPlayerRepositroy.cs:
Player AddPalyer(Player player);

To capture the data of the object posted from the client, we need to create GraphQL type which inherits 'GraphQL.Types.InputObjectGraphType<T>'. InputObjectGraphType looks similar to ObjectGraphType, but InputObjectGraphType to capture the data from client wherea as ObjectGraphType to serve the type of data to clients. Now in 'GraphQLTypes' folder add a new file as 'InputPlayerType.cs'

InputPlayerType.cs:
using GraphQL.Types;
using GraphQLSample.Models;

namespace GraphQLSample.GraphQLTypes
{
    public class InputPlayerType:InputObjectGraphType<Player>
    {
        public InputPlayerType()
        {
            Name = "InputPlayerType";
            Field(_ => _.Id);
            Field(_ => _.FirstName);
            // description is an self 
            //explanatory extenstion method which is options
            Field(_ => _.LastName).Description("last name of a player");
            Field(_ => _.CurrentAge);
            Field(_ => _.Teams);
            Field(_ => _.PlayingRole);
            Field(_ => _.BattingStyle);
            Field(_ => _.BowlingStyle);
        }
    }
}
Now Register InputPlayerType in ConfigureServices method in Startup.cs:
services.AddSingleton<InputPlayerType>();
Now in 'GraphQLTypes' folder create a new file 'RootMutation.cs' as below:
using GraphQL.Types;
using GraphQLSample.Models;
using GraphQLSample.Repositories;

namespace GraphQLSample.GraphQLTypes
{
    public class RootMutation : ObjectGraphType
    {

        public RootMutation(IPlayerRepository playerRepository)
        {
            Field<PlayerType>(
                "addPlayer",
                arguments: new QueryArguments
                {
                    new QueryArgument<InputPlayerType>(){ Name = "player" }
                },
                resolve: context =>
                {
                    var player = context.GetArgument<Player>("player");
                    return playerRepository.AddPalyer(player);
                }
                );
        }
    }
}
Now configure RootMutation in RootSchema.cs as below:
public RootSchema(IDependencyResolver resolver):base(resolver)
{
 Query = resolver.Resolve<RootQuery>();
 Mutation = resolver.Resolve<RootMutation>();
}
Now Register RootMutation in ConfigureSevices method in Startup.cs as below:
services.AddScoped<RootMutation>();
Now modify 'GraphQLQueryDto' as below
public class GraphQLQueryDto
{
    public string Query { get; set; }
    public string Variables { get; set; }
}
Here 'Variables' property is like input data to 'Query' property. Now update 'GraphQLController' post method as below:
var result = await _executer.ExecuteAsync(_ =>
{
 _.Schema = _schema;
 _.Query = query.Query;
 _.Inputs = query.Variables?.ToInputs();
 
}).ConfigureAwait(false);
The variable value was assigned to the "Inputs" type in DocumentExecuter, where this variable values passed as data to 'Query' variables at runtime.

The query for Mutation:
mutation($player: InputPlayerType) {
 addPlayer(player: $player) {
  id
  firstName
 }
}
  • mutation keyword to represent GraphQL Mutations. 
  • '$player' is a variable whose values will pass from GraphQL 'Variables'.  
  • 'InputPlayerType' is assigned a type of '$player', it should match with the name of the 'InputObjectGraphType' we declared in the above steps. 
  • 'addPlayer' represents Field name in 'RootMutation' as we mentioned above steps. 'player'  argument of 'addplayer' Field.
Variables of the above Mutation query:
{
"player":{
  "id":0
  "firstName": "Shikar",
  "lastName": "Dhawan",
  "currentAge": 30,
  "teams": "India",
  "playingRole": "Opening Batsman",
  "battingStyle": "Left-hander",
  "bowlingStyle": "N/A"
}
}
Variable is a plain JSON Object.
Now test the API with GraphQL Mutations

Summary:

We have discussed the core feature of the GraphQL API. We learned how GraphQL API is different from REST API. We did a hands-on sample of integrating GraphQL API into the Asp.Net Core application. 

Source Code:

Follow Me:

Comments

  1. Best tutorial I found so far - and nicely laid out. Thank-you.

    Just having an issue with the final sample where you explain the mutation. The query arg in the controller is null no matter how I format it in postman.
    I downloaded the code to make sure I followed the examples correctly and it appears I have.
    Any ideas?

    ReplyDelete
    Replies
    1. Hi DominionZA,
      payload for mutation
      {
      "query":"mutation($player: InputPlayerType) { addPlayer(player:$player){id firstName} }",
      "variables":"{\"playe\":{\"id\":0, \"firstName\":\"rahul\",\"lastName\":\"KL\",\"currentAge\":30,\"teams\":\"India\",\"playingRole\":\"Wicket Keeper\",\"battingStyle\":\"Left-hander\",\"bowlingStyle\":\"N/A\"}}"
      }

      Delete

Post a Comment

Popular posts from this blog

Endpoint Routing In Asp.Net Core

How Routing Works In  Core 2.1 And Below Versions?: In Asp.Net Core routing is configured using app.UseRouter() or app.UseMvc() middleware. app.UseMvc(routes => { routes.MapRoute( name: "default", template: "{controller=Home}/{action=Index}/{id?}"); }); Here in Dotnet Core version 2.1 or below versions on the execution of route middleware request will be navigated appropriate controller matched to the route. An operation or functionality which is dependent on route URL or route values and that need to be implemented before the execution of route middleware can be done by accessing the route path from the current request context as below app.Use(async (context, next) => { if(context.Request.Path.Value.IndexOf("oldvehicle") != -1) { context.Response.Redirect("vehicle"); } else { await next(); } }); app.UseMvc(routes => { routes.MapRoute( name: "vehicleRoute", template: "vehicle", defaul

ASP.NET Core Web API Versioning

Introduction: An iteration and evolutionary changes of an ASP.NET Core Web API is handled by Versioning. Versioning of an API gives confidence to the clients which consumes API for a long time. Any changes or development of an API will be accessible using the new version and it won't cause issues to the clients consuming the old version of API. When To Use Versioning: Any API response changes. Developing an API by implementing testing levels like 'Alpha', 'Beta', and 'RC' versions before releasing Production. Deprecating an API which means API going to be removed or upgraded by a version within a short period. Versioning Types: Query String Versioning Url Path Versioning Media Type Versioning API Version Nuget: To Configure versioning to AspNet Core Web API Microsoft provided a library(Microsoft.AspNetCore.Mvc.Versioning). So to use the versioning library please install NuGet below.              Install-Package Microsoft.A

.NET Core MVC Application File Upload To Physical Location With Buffered Technique

Buffering Technique In File Upload: The server will use its Memory(RAM) or Disk Storage to save the files on receiving a file upload request from the client.  Usage of Memory(RAM) or Disk depends on the number of file requests and the size of the file.  Any single buffered file exceeding 64KB is moved from Memory to a temp file on disk.  If an application receives heavy traffic of uploading files there might be a chance of out of Disk or RAM memory which leads to crash application. So this Buffer technique used for small files uploading. In the following article, we create a sample for the file uploading using .NET Core MVC application. Create The .NET Core MVC Project: Let's create a .NET Core MVC project, here for this sample I'm using Visual Studio Code as below.   Check the link to use the Visual Studio Code for .NET Core Application . IFormFile: Microsoft.AspNetCore.Http.IFormFile used for file upload with buffered technique. On uploading files f

Ionic Picker Sample Code In Angular

Introduction: Ionic Picker(ion-picker) is a popup slides up from the bottom of the device screen, which contains rows with selectable column separated items. The main building block of ion-picker as follows: PickerController PickerOptions PickerController: PickerController object helps in creating an ion-picker overlay. create(opts?: Opts): Promise<Overlay> PickerController create method helps in create the picker overlay with the picker options PickerOptions: PickerOptions is a configuration object used by PickerController to display ion-picker. Single Column Ionic Picker: single.item.picker.ts: import { Component } from "@angular/core"; import { PickerController } from "@ionic/angular"; import { PickerOptions } from "@ionic/core"; @Component({ selector: "single-column-picker", templateUrl:"single.item.picker.html" }) export class SingleItemPicker { animals: string[] = ["Tiger&quo

Asp.Net Core MVC Form Validation Techniques

Introduction: Form validations in any applications are like assures that a valid data is storing on servers. All programing frameworks have their own individual implementations for form validations. In Dotnet Core MVC application server-side validations carried on by the models with the help of Data Annotations and the client-side validations carried by the plugin jQuery Unobtrusive Validation. jQuery Unobtrusive Validation is a custom library developed by Microsoft based on the popular library  jQuery Validate . In this article, we are going to learn how the model validation and client-side validation works in Asp.Net Core MVC Application with sample examples. Getting Started: Let's create an Asp.Net Core MVC application project using preferred editors like Microsoft Visual Studio or Microsoft Visual Studio Code. Here I'm using Visual Studio. Let's create an MVC controller and name it as 'PersonController.cs' and add an action method as bel

How Response Caching Works In Asp.Net Core

What Is Response Caching?: Response Caching means storing of response output and using stored response until it's under it's the expiration time. Response Caching approach cuts down some requests to the server and also reduces some workload on the server. Response Caching Headers: Response Caching carried out by the few Http based headers information between client and server. Main Response Caching Headers are like below Cache-Control Pragma Vary Cache-Control Header: Cache-Control header is the main header type for the response caching. Cache-Control will be decorated with the following directives. public - this directive indicates any cache may store the response. private - this directive allows to store response with respect to a single user and can't be stored with shared cache stores. max-age - this directive represents a time to hold a response in the cache. no-cache - this directive represents no storing of response and always fetch the fr

Blazor Server CRUD Operations

Introduction: Blazor Server is a web framework to develop server-side single-page applications. Blazor is made up of components with the combinations on C#, Html, CSS.  Blazor Server is production-ready from the .Net Core 3.0.  Blazor Server Working Mechanism: Blazor Server is a very light-weight web development framework.  In Blazor Server, not all code gets downloaded to the client browsers. Blazor Server made of components these components can be a block of code or page with respective navigation.  Blazor server application communicates with the server with a SignalR background connection which is inbuilt functionality. Application click,  form submission, change events, application page navigation every operation is carried out by the SignalR connection by communicating with the server.  Blazor updates the Html DOM very gently on every data update without any overhead. Blazor Server application maintains a nice intelligent tree structure to update the required inform

NestJS API CRUD Operations With MongoDB

Introduction: NestJS is a framework used to develop server-side applications. NestJS built on top of Node.js frameworks like Express. It is a combination of Progressive Javascript, Object-Oriented Programming, Functional Programming, and Functional Reactive Programming. Nest CLI Installation: Using Nest CLI we are able to generate the NestJS starter project with the default template. To install Nest CLI globally over our system open command prompt and run the command               npm i -g @nestjs/cli Now create a sample project by using Nest CLI command              nest new your_project_name package.json: Now open the package.json file from the sample application created, you can observe few properties like "scripts", "dependencies", and "devDependencies". "dependencies" contains all plugins to be installed and used them to run the application. "devDependencies" contain all plugins to be installed and used them

Blazor WebAssembly Dynamic Form Validation

Introduction: In Blazor WebAssembly(client-side framework) form validation can be done with Data Annotations. Using Data Annotations we can validate form either by default validation attributes or by creating custom validation attributes. Using this Data Annotation attribute we can dynamically add or remove validation on a specific field in a form. Create Blazor WebAssembly Project: To create a Blazor WebAssembly template project need to install the latest version of VisualStudio 2019 for rich intelligence support or we can use VisualStudio code but less intelligence support from the editor.  Click here to know about Blazor WebAssembly template creation. Blazor WebAssembly is in preview mode, not yet ready for production. Create Razor Component: After creating a sample project using the Blazor WebAssembly template, in "Pages" folder add new Razor Component , name it as "UserForm.razor" Add Route: In Blazor routing can be configured using @