Today, we will delve into one of the modern API architectures.
We'll develop a simple gRPC service using .NET C# that performs CRUD (Create, Read, Update, Delete) operations.
gRPC is a modern, open-source, high-performance Remote Procedure Call (RPC) framework that can run in any environment. It enables client and server applications to communicate transparently and simplifies the building of connected systems. gRPC is based on the idea of defining a service and specifying the methods that can be called remotely with their parameters and return types. On the server side, the server implements this interface and runs a gRPC server to handle client calls. On the client side, the client has a stub that provides the same methods as the server.
gRPC is designed to work with a variety of programming languages, making it an ideal choice for multi-language systems. It uses Protocol Buffers (protobuf) as its Interface Definition Language (IDL) and its underlying message interchange format, which is a powerful binary serialization toolset and language.
History of gRPC
gRPC was initially created by Google and is a part of the Cloud Native Computing Foundation (CNCF). It was publicly announced in February 2015 and has evolved from the earlier Stubby, an RPC system that Google developed internally to connect their large-scale microservices.
One of the main reasons for developing gRPC was to address the need for efficient communication in microservices architectures where lightweight data exchange is crucial. gRPC's use of HTTP/2 as the transport protocol allows for features like concurrently streaming data in both directions, multiplexing multiple requests over a single connection, header compression, etc.
The evolution of gRPC is marked by its adoption across various organizations outside Google for both internal microservices communication and client-facing APIs. It supports several languages and platforms, providing developers with a versatile tool for building distributed systems.
Prerequisites
- Visual Studio 2019 or later with the ASP.NET and web development workload.
- .NET 5.0 SDK or later.
- A basic understanding of gRPC.
Step 1. Set up the .NET Core gRPC Project
- Open Visual Studio.
- Click on "Create a new project."
- Search for the "gRPC Service" template and select it. Click "Next."
- Name the project BookGrpcService and the solution BookGrpcService. Click "Create."
Step 2. Define the Proto File
Create or update the Protos/book.proto file. This protocol buffer file defines the structure of the gRPC service and the messages that are exchanged.
syntax = "proto3";
option csharp_namespace = "BookGrpcService";
package book;
// The Book service definition
service Books {
rpc CreateBook (CreateBookRequest) returns (Book);
rpc GetBook (GetBookRequest) returns (Book);
rpc UpdateBook (UpdateBookRequest) returns (Book);
rpc DeleteBook (DeleteBookRequest) returns (DeleteBookResponse);
rpc ListBooks (ListBooksRequest) returns (ListBooksResponse); // Adding this line
}
// The request message containing the ID
message GetBookRequest {
int32 id = 1;
}
// The request message containing the book details
message CreateBookRequest {
string title = 1;
string author = 2;
}
// The request message containing full book information
message UpdateBookRequest {
int32 id = 1;
string title = 2;
string author = 3;
}
// The request message for deleting book by ID
message DeleteBookRequest {
int32 id = 1;
}
// The response message containing status
message DeleteBookResponse {
string status = 1;
}
message ListBooksRequest {}
message ListBooksResponse {
repeated Book books = 1; // A list of books
}
// The message representing a Book
message Book {
int32 id = 1;
string title = 2;
string author = 3;
}
Step 3. Implement the Service in C#
create a new service implementation in Services/BookService.cs that supports CRUD operation based on the Proto file.
using Grpc.Core;
using System.Collections.Generic;
using System.Threading.Tasks;
using BookGrpcService;
namespace BookGrpcService.Services
{
public class BooksService : Books.BooksBase
{
private static readonly List<Book> books = new List<Book>
{
new Book { Id = 1, Title = "1984", Author = "George Orwell" },
new Book { Id = 2, Title = "Brave New World", Author = "Aldous Huxley" },
new Book { Id = 3, Title = "To Kill a Mockingbird", Author = "Harper Lee" }
};
private static int nextId = 4;
public override Task<Book> CreateBook(CreateBookRequest request, ServerCallContext context)
{
var book = new Book
{
Id = nextId++,
Title = request.Title,
Author = request.Author
};
books.Add(book);
return Task.FromResult(book);
}
public override Task<Book> GetBook(GetBookRequest request, ServerCallContext context)
{
var book = books.Find(b => b.Id == request.Id);
return Task.FromResult(book);
}
public override Task<ListBooksResponse> ListBooks(ListBooksRequest request, ServerCallContext context)
{
ListBooksResponse response = new ListBooksResponse();
response.Books.AddRange(books);
return Task.FromResult(response);
}
public override Task<Book> UpdateBook(UpdateBookRequest request, ServerCallContext context)
{
var book = books.Find(b => b.Id == request.Id);
if (book != null)
{
book.Title = request.Title;
book.Author = request.Author;
}
return Task.FromResult(book);
}
public override Task<DeleteBookResponse> DeleteBook(DeleteBookRequest request, ServerCallContext context)
{
var book = books.Find(b => b.Id == request.Id);
if (book != null)
{
books.Remove(book);
return Task.FromResult(new DeleteBookResponse { Status = "Deleted" });
}
return Task.FromResult(new DeleteBookResponse { Status = "Book Not Found" });
}
}
}
Step 4. Regenerate the gRPC code
Ensure to rebuild the project to regenerate the C# gRPC code automatically.
Step 5. Testing the Service
Run the project in Visual Studio by hitting F5. Use a gRPC client tool like BloomRPC gRPC URL or PostMan to test each service operation by sending the respective requests.
Testing in Postman
- Open the Postman, click on New, and choose the gRPC option.
- Import the Proto file in Postman.
- Select the ListBooks options and send a request.
- Now, we will add a new book to the list using the CreateBook option.
- This gRPC service supports Create, Delete, Update, Get, and List operations. You can try it out in Postman.
Conclusion
We have successfully established a foundational gRPC service using .NET and C#. Through the implementation of a simple book management system, we have learned how to define a .proto file to structure our gRPC service and messages, and have seen how these definitions translate into server-side logic in C#.
gRPC offers significant advantages in terms of performance and flexibility when compared to traditional REST APIs, particularly in microservices architectures where efficient communication between services is crucial. Its use of HTTP/2 for transport, low overhead, and ability to generate cross-platform client and server code makes gRPC a powerful choice for modern application development.