In this article, we will discuss gRPC and perform CRUD Operation using that and step-by-step implementation of gRPC.
We take Product Application here to understand how things are going to work with gRPC and, in that first, we create ProductOfferGrpcService which is used to create Product Offers and which will be consumed by Admin Service and he will add, update and delete product offer and managed all the things related to that using gRPC Service. Secondly, we create another section in ProductOfferGrpcService for the User to get a list of offers which is added by the admin.
Agenda
- Introduction of gRPC
- Implementation of ProductOfferGrpcService and Admin.API Microservice
- Implementation of User Console Application
Prerequisites
- Visual Studio 2022
- .NET Core 6 SDK
- SQL Server
Introduction of gRPC
- gRPC stands for Google Remote Procedure Calls
- gRPC is a modern open-source high-performance Remote Procedure Call (RPC) framework that can run in any environment. It can efficiently connect services in and across data centers with pluggable support for load balancing, tracing, health checking, and authentication. It is also applicable in the last mile of distributed computing to connect devices, mobile applications, and browsers to backend services. – gRPC Page

- gRPC is the framework that is used to implement APIs using HTTP/2
- Basically, gRPC uses the protobuf for serialization and HTTP2 protocol which provides lots more advantages than HTTP
- gRPC clients and servers intercommunicate utilizing a variety of environments and machines, It Also supports many languages like Java, C#, Go, Ruby and Python.
- The Binary layer of gRPC will do all data operations like encoding and it also uses protobuf as an intermediator between client and server, improving performance.
- It is also used for communication between multiple microservices efficiently
If you want some more details about gRPC and how it will work then I suggest you read my following article
Implementation of ProductOfferGrpcService Service
Step 1
Create a new Blank Solution

Step 2
Configure Project

Step 3
Add a new gRPC Service Project inside the Blank Solution

Step 4
Configure your new project

Step 5
Provide additional information

Remove default protobuf and service file from the project
Project Structure

Step 6
Create Offer Class inside the Entities
namespace ProductOfferGrpcService.Entities
{
public class Offer
{
public int Id { get; set; }
public string ProductName { get; set; }
public string OfferDescription { get; set; }
}
}
Step 7
Next, Create a new DbContextClass inside the Data folder
using Microsoft.EntityFrameworkCore;
using ProductOfferGrpcService.Entities;
namespace ProductOfferGrpcService.Data
{
public class DbContextClass : DbContext
{
protected readonly IConfiguration Configuration;
public DbContextClass(IConfiguration configuration)
{
Configuration = configuration;
}
protected override void OnConfiguring(DbContextOptionsBuilder options)
{
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"));
}
public DbSet<Offer> Offer { get; set; }
}
}
Step 8
Later on, create IProductOfferService and ProductOfferService inside the Repositories folder
IProductOfferService
using ProductOfferGrpcService.Entities;
namespace ProductOfferGrpcService.Repositories
{
public interface IProductOfferService
{
public Task<List<Offer>> GetOfferListAsync();
public Task<Offer> GetOfferByIdAsync(int Id);
public Task<Offer> AddOfferAsync(Offer offer);
public Task<Offer> UpdateOfferAsync(Offer offer);
public Task<bool> DeleteOfferAsync(int Id);
}
}
ProductOfferService
using Microsoft.EntityFrameworkCore;
using ProductOfferGrpcService.Data;
using ProductOfferGrpcService.Entities;
namespace ProductOfferGrpcService.Repositories
{
public class ProductOfferService : IProductOfferService
{
private readonly DbContextClass _dbContext;
public ProductOfferService(DbContextClass dbContext)
{
_dbContext = dbContext;
}
public async Task<List<Offer>> GetOfferListAsync()
{
return await _dbContext.Offer.ToListAsync();
}
public async Task<Offer> GetOfferByIdAsync(int Id)
{
return await _dbContext.Offer.Where(x => x.Id == Id).FirstOrDefaultAsync();
}
public async Task<Offer> AddOfferAsync(Offer offer)
{
var result = _dbContext.Offer.Add(offer);
await _dbContext.SaveChangesAsync();
return result.Entity;
}
public async Task<Offer> UpdateOfferAsync(Offer offer)
{
var result = _dbContext.Offer.Update(offer);
await _dbContext.SaveChangesAsync();
return result.Entity;
}
public async Task<bool> DeleteOfferAsync(int Id)
{
var filteredData = _dbContext.Offer.Where(x => x.Id == Id).FirstOrDefault();
var result = _dbContext.Remove(filteredData);
await _dbContext.SaveChangesAsync();
return result != null ? true : false;
}
}
}
Step 9
Create OfferMapper inside AutoMapper folder
using AutoMapper;
using ProductOfferGrpcService.Entities;
using ProductOfferGrpcService.Protos;
namespace ProductOfferGrpcService.AutoMapper
{
public class OfferMapper : Profile
{
public OfferMapper()
{
CreateMap<Offer, OfferDetail>().ReverseMap();
}
}
}
Step 10
Next, create a new offer proto file inside Proto
syntax = "proto3";
option csharp_namespace = "ProductOfferGrpcService.Protos";
service ProductOfferService {
rpc GetOfferList (Empty) returns (Offers);
rpc GetOffer (GetOfferDetailRequest) returns (OfferDetail);
rpc CreateOffer (CreateOfferDetailRequest) returns (OfferDetail);
rpc UpdateOffer (UpdateOfferDetailRequest) returns (OfferDetail);
rpc DeleteOffer (DeleteOfferDetailRequest) returns (DeleteOfferDetailResponse);
}
message GetOfferDetailRequest {
int32 productId = 1;
}
message OfferDetail {
int32 id = 1;
string productName = 2;
string offerDescription = 3;
}
message CreateOfferDetailRequest {
OfferDetail offer = 1;
}
message UpdateOfferDetailRequest {
OfferDetail offer = 1;
}
message DeleteOfferDetailRequest {
int32 productId = 1;
}
message DeleteOfferDetailResponse {
bool isDelete = 1;
}
message Empty{
}
message Offers {
repeated OfferDetail items = 1;
}
Also, make sure proto file properties are correct as I showed below and if that will be correct then build your project

Step 11
Add a new Offer Service inside Services
using AutoMapper;
using Grpc.Core;
using ProductOfferGrpcService.Entities;
using ProductOfferGrpcService.Protos;
using ProductOfferGrpcService.Repositories;
using ProductOfferService = ProductOfferGrpcService.Protos.ProductOfferService;
namespace ProductOfferGrpcService.Services
{
public class OfferService : ProductOfferService.ProductOfferServiceBase
{
private readonly IProductOfferService _prductOfferService;
private readonly IMapper _mapper;
public OfferService(IProductOfferService prductOfferService, IMapper mapper)
{
_prductOfferService = prductOfferService;
_mapper = mapper;
}
public async override Task<Offers> GetOfferList(Empty request, ServerCallContext context)
{
var offersData = await _prductOfferService.GetOfferListAsync();
Offers response = new Offers();
foreach (Offer offer in offersData)
{
response.Items.Add(_mapper.Map<OfferDetail>(offer));
}
return response;
}
public async override Task<OfferDetail> GetOffer(GetOfferDetailRequest request, ServerCallContext context)
{
var offer = await _prductOfferService.GetOfferByIdAsync(request.ProductId);
var offerDetail = _mapper.Map<OfferDetail>(offer);
return offerDetail;
}
public async override Task<OfferDetail> CreateOffer(CreateOfferDetailRequest request, ServerCallContext context)
{
var offer = _mapper.Map<Offer>(request.Offer);
await _prductOfferService.AddOfferAsync(offer);
var offerDetail = _mapper.Map<OfferDetail>(offer);
return offerDetail;
}
public async override Task<OfferDetail> UpdateOffer(UpdateOfferDetailRequest request, ServerCallContext context)
{
var offer = _mapper.Map<Offer>(request.Offer);
await _prductOfferService.UpdateOfferAsync(offer);
var offerDetail = _mapper.Map<OfferDetail>(offer);
return offerDetail;
}
public async override Task<DeleteOfferDetailResponse> DeleteOffer(DeleteOfferDetailRequest request, ServerCallContext context)
{
var isDeleted = await _prductOfferService.DeleteOfferAsync(request.ProductId);
var response = new DeleteOfferDetailResponse
{
IsDelete = isDeleted
};
return response;
}
}
}
Step 12
Configure the database connection string inside the app settings file
{
"ConnectionStrings": {
"DefaultConnection": "Data Source=DESKTOP;;Initial Catalog=ProductOfferAsync;User Id=sa;Password=database;"
},
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*",
"Kestrel": {
"EndpointDefaults": {
"Protocols": "Http2"
}
}
}

















Tomas WangerPosted Nov 25, 2022, 5:43 PM
Jaydeep, this is perfect. Thank you! Question: any insights on how to deploy gRPC server to IIS?
luis cocoPosted Sep 16, 2022, 4:43 AM
Dear Jaydeep, I would like to know if it is necessary to run the command Update-Database before running the application for creating the table, and also before this operation create the database "ProductOfferAsync" in the SQL Server.Could you please explain, with more details, the required steps for running the apps?. Best, Luis